领域驱动设计
依次分为用户界面层,应用层,领域层,基础设施层 各层主要任务
用户界面层:想用户显示信息和解释用户指令。
应用层:定义软件要完成的任务,并指挥表达领域概念的对象来解决问题。应用层应尽量简单,不包含业务规则或知识,而只是为下一层中的领域对象协调任务,分配工作,屎他们相互合作。他没有反映业务情况的状态,但是却可以具有另外一种状态,为用户或程序显示某个任务的进度。
领域层(模型层) :负责表达业务概念,业务状态信息以及业务规则。尽管保存业务状态的技术细节是由基础设施层实现,但是反映业务情况的状态是由本曾控制并使用的。此层是软件的核心。
基础设施层: 为上面各层提供通用的技术能力,为应用层传递消息,为领域层提供持久化机制,为用户界面绘制屏幕组件,等等。基础设施层还能通过架构框架来支持四个层间的交互模式。
例子
为网上银行功能分层
比如转账功能, 牢记 处理基本业务规则的是领域层而不是应用层 , 如A转给B100元 则 应用层提供 transfer(A,B,100)服务,领域层则提供具体转账服务,和规则控制,应用层只是通知机制,通知领域层进行一些列活动,应用层不该涉及领域层知识。
各层之间应该是上层依赖与下层,但是当下层需要和上层通信时需要依赖于回调模式或观察者模式。
软件中所表示的模型
1.关联
关联可以有多种,一对一,一对多,多对多,关联越复杂则实现会更加复杂,所以我们需要对关联进行处理减少不必要的关联,下面3种方法让关联更难控制。
1)规定一个遍历方向
2)添加一个限定符,以便有效减少多重关联
3)消除不必要的关联
坚持将关联限定为领域中所偏重的方向,不仅可以提高这些关联的表达力并简化其实现,而且还可以突出剩下的双向关联的重要性
2,Entity
实体有一下两个特性
1)他在整个生命周期中有连续性
2)他是一些对用户来说非常重要的不同状态不是由属性决定的。
Entity建模
Entity 最重要的职责是确保连续性,一边其行为更清楚且可以预测,保持实体简练是实现这一责任的关键,抓住Entity对象定义的最基本特征,尤其是那些用于识别 查找或者匹配对象的特征。只添加那些对概念至关重要的行为和这些行为所必要的属性。此外,应该把行为和属性转移到与核心实体关联的其他对象中
抽象出与Entity标识相关的属性与其放在一起,其它放入其他Entity或者值对象中。
3.VALUE OBJECT
用于描述领域的某方面而本身没有概念表示的对象成为VALUE OBJECT 。
比如一个邮政公司需要用地址来投递包裹,如果一个人室友也从同一家公司定了货物,则他们是否住在一起不重要,则地址是VALUE OBJECT
如果一个宿舍他们停电了,几个室友各自打电话申报服务,那么这时地址就是Entity。
Value Object 经常作为参数在对象之间传递消息。他们通常是临时对象,在一次操作中被创造,然后丢弃。VALUE OBJECT 可以作为ENTITY的属性。我们可以把一个人定义为一个ENTITY ,把他的名字定义为VALUE OBJECT
VALUE OBJECT 的设计
包括共享和复制。 FLYWEIGHT模式可以实现共享VALUE OBJECT
共享和复制的使用
以下情况使用共享
1)节省数据库空间或减少对象数量是关键要求时
2)当通信开销很低时(中央服务器)
3)共享对象被严格限定不可变的时候
只要VALUE OBJECT 是不可变的,变更管理会很简单,因为除了整体替换外没有其他的更改。
再次强调 如果一个VALUE 的实现是可变的那么就不能共享他。无论是否共享Value 在设计的时候都要把他们设计成不可变的,这样有利于后期的重构和优化。
通过VALUE OBJECT 优化数据库设计。通过复制可将多个属性放于同一页面减少查询耗时。 VALUE OBJECT 的关联是没有意义的。
4.Service
有些重要的操作不适合归类到Entity 和ValueObejct 中 所以抽象除了领域层中的Service,Service应该定义为无状态的,就是说任何客户都可以使用Service的任何实例,而不必关心Service的历史状态。
领域层Service和应用层的区分。 应用层负责安排一个通知,领域层负责确定他是否满足临界值。
领域对象的生命周期
1.主要挑战
1)整个生命周期中的维护完整性
2)防止模型陷入管理生命周期复杂性造成的困境中。
模式 :Aggregate(聚合)
固定规则:指在数据变化时必须保持不变的一致性规则。
为了实现概念上的Aggregate,需要实现一下规则
1)根entity具有全局标识,它最终负责检查固定规则
2)根entity具有全局标识。边界内的Entity具有本地标识,这些标识只有在Aggregate内部才是唯一的。
3)Aggregate外部对象不能直接引用除根Entity之外的任何内部对象。根entity可以把对内部entity的引用传递给他们,但这些对象只能临时使用这些引用,而不能保持引用
4)只有Aggregate跟才能通过数据库查询获取。所有其他对象必须通过关联的遍历才能找到,
5)Aggreate内部可以保持对根的引用
6)删除操作要一次删除Aggergate边界内所有对象
7)当提交对聚集边界内任何对象修改的时候,固定规则需要满足。
Factory将对象创建这一操作抽象出来。好的工厂满足一下两项。
1)每个创建方法都是原子方法,而且满足被创建对象或聚集的所有固定规则
2)Factory应该被抽象为所需的类型,而不是创建出具体的类。
Factory 通常不表示模型的任何部分,但他们是领域的一部分,能是模型更明确的表示出对象
REPOSITORY
REPOSITORY
负责对象的持久化和重建。