结合领域驱动设计的SOA分布式软件架构,你还在为这些烦恼?

一、SOA与DDD的定义SOA与DDD都是常用的系统架构 , 但两者之间所针对的核心是不同的 。
SOA(面向服务架构)由Gartner 在1996年提出来 , 它是一种分布式的软件架构 , 它可以根据需求通过网络对松散耦合的粗粒度应用组件进行部署、组合和使用 。 简单来说 , SOA就是一种大型系统开发的体系架构 , 在基于SOA架构的系统中 , 具体应用程序的功能是由一些松耦合并且具有统一接口的组件(也就是service)组合构建起来的 , 它是针对多核心多平台之间的数据交换 。
DDD(领域驱动设计)由Eric Evans在2004提出 , 它的核心内容是“如何将业务领域概念映射到软件工程当中” 。 它推翻了“软件从数据层开发设计”的旧习惯 , 强调领域模型在软件中发挥的强大力量 , 注重如何把企业内部复杂的业务流程转化为软件 。
也许可以认为SOA针对的是大型系统的总体架构 , 注重如何把系统进行项目分离 , 隔离开发 , 最后实现系统合并 。 而DDD是针对单个项目的开发管理过程 , 注重如何利用领域模型把业务需求转化为软件 。 两者之间并没有存在理论上的冲突 , 能把两者结合 , 各展所长 , 更能发挥各自的优势 。
二、DDD的分层结构1. 概念
从概念上来说 , 领域驱动设计架构主要分为基础设施层、领域层、应用层、表现层4个概念层 。
基础结构层:是为各层提供各项通用技术能力而构建的 , 它可以为领域层提供像Hibernate、LINQ、ADO.NET等持久化机制 , 为应用层传递消息 , 为表现层提供插件等等 。
领域层:它是系统的核心部分 , 代表业务的逻辑概念 。 它会根据业务的实际流程定制了业务信息以及业务规则 , 并按一定的关系制定领域模型 。 领域模型尽管需要依赖基础结构层进行保存 , 但领域模型之间的逻辑关系是跟基础结构层相隔离的 。 即使基础结构层从NHibernate技术转换成LINQ技术 , 也不会影响到领域层的结构 。 领域模型只会依赖实际的业务逻辑 , 它只会根据业务的转变而灵活变动 。
应用层:它的任务是协调领域层与表现层之间的关系 , 也可以作为系统与外界沟通的桥梁 , 在这层里面不会包括任何的业务逻辑 。 在SOA面向服务架构 , 这一层起着重要的作用 , 在第七节将详细说明 。
表现层:它是常用的界面开发 , 可以以页面(ASP.NET、JSP) , 窗口(WinForm、WPF、Swing)等形式表现 , 它的主要职责是负责与用户进行信息沟通 。 (注意:在一般的项目开发中 , Web服务会作为与外界通讯的接口放置在表现层中 , 但在SOA中 , Web服务会大多置于应用层中 , 下面将会作进一步解释)
结合领域驱动设计的SOA分布式软件架构,你还在为这些烦恼?文章插图
2. 开发实例
在此先举个常见的订单管理例子 , 在下面的章节里都会以这个实例为参考:
每个用户在Person表里面都会有一个对应的帐户 , 里面记录了用户的姓名、地址、电话、积分(Point)等基本信息 。
在Order表里记录的是每次交易的过程 , 每次商品的送货费(Freightage)为10元 , 当商品价格(Price)超过98元可免费送货 , 当用户Person积分(Point)超过2000分可获7折优惠(Favorable) , 1000~2000分可获8折 , 1000分以下可有9折 , 最后总体价格为为(TotalPrice) 。
在最后结单的时候Order表里会产生订单号码OrderNumber和下订日期Delivery , Person表的积分也会加上订单总价的点数 。
最后OrderItem表包含了物品Goods、物品价格Price、购买数量Count等属性 , 它主要记录每次订单的详细交易状况 。
上面的业务逻辑跟淘宝、当当等等大型购物网基本相似 。 之所以用这样一个例子作为参考 , 是想表现一下DDD是如何利用领域模型去适应多变的业务逻辑关系 。
三、把业务关系转化为领域模型1. 概念
模型驱动设计设计(MODEL-DRIVEN-DESIGN)是DDD里面的核心 , 它代表的是各个对象之间的关系 , 把复杂的逻辑关系转化为模型 。
模型主要分为实体(Entity)、值对象(Value Object)与服务(Service)三种 。
实体:实体所包含的不单止是一连串的属性 , 更重要的是与事件的联系 , 在一个生命周期中环境的变化与事件发生 , 将引起实体内部产生变化 。 好像在实体Order里面 , Person的积分(Point)和OrderItem的价格(Price)都会直接影响总体价格(TotalPrice)的大小 , 而总体价格也会影响到运费Freightage的多少等等 。 在Order实体的一切 , 都会受到Person、OrderItem等这些外部因素的影响 , 这样的对象被视为实体 。 在不同的时刻 , 实体会有不同的状态 , 所以在开发过程中我们需要为实体加上一个“标识符”来区分对象的身份 , 它是实体的生命周期里的唯一标志 。