什么是领域驱动设计?
以一种统一的模型,去描述一个软件,这种模型具有能让设计者,开发者,领域专家都能理解。
领域驱动设计的经典分层架构?
用户界面 | 应用层 | 领域层 | 基础设施层
应用层:用于定义软件要完成的所有任务
领域层:表达任务
基础设施层:为其他层提供技术需求,提供层间通信
实体:区分实体:唯一标识
值对象:不关注唯一标识,如果对象所有的值都相等,那么将它们看作同一个值对象
领域服务:领域中有一些概念不适合建立对象,它们本身就是一些操作,且跨越多个领域对象,不适合强行将这些操作分配给一个对象。跨多个对象的操作:领域服务。
领域服务:还可以避免领域知识泄露到应用层:没有领域服务便会调用领域对象。
软件的三种服务:应用层服务,领域服务,基础服务。
应用层服务
- 获取输入(如一个XML请求);
- 发送消息给领域层服务,要求其实现转帐的业务逻辑;
- 领域层服务处理成功,则调用基础层服务发送Email通知;
领域层服务
- 获取源帐号和目标帐号,分别通知源帐号和目标帐号进行扣除金额和增加金额的操作;
- 提供返回结果给应用层;
基础层服务
按照应用层的请求,发送Email通知;
聚合:一组具有内聚关系的相关对象的集合,我们把聚合看作是一个修改数据的单元。
内聚关系:对象之间清晰的所属关系和边界
聚合(aggregate):
1.一个聚合有:一个根(聚合内的某个实体)、一个边界。边界定义了一个聚合内部有哪些实体或值对象
2.聚合内部的对象可以相互引用。聚合外部访问聚合内部对象,通过聚合根。
3.聚合内除根以外的其他实体的唯一标识都是本地标识,也就是只要在聚合内部保持唯一即可,因为它们总是从属于这个聚合的;在聚合外有重复不影响。
4.基于聚合的以上概念,推论出从数据库查询时的单元也是以聚合为一个单元,也就是说我们不能直接查询聚合内部的某个非根的对象;
5.聚合内部的对象可以保持对其他聚合根的引用;
6.删除一个聚合根时必须同时删除该聚合内的所有相关对象,因为他们都同属于一个聚合,是一个完整的概念;
仓储(Repository):用于管理对象,添加或者移除对象。
1.仓储里面存放的一定是聚合
2.仓储分为仓储定义和仓储实现
3.仓储一般不负责事务处理。一般事务处理会交给一个叫“工作单元 Unit Of Work”
4.仓储在设计查询接口时,可能还会用到规格模式(Specification Pattern)
关于Unit of Work(工作单元)的几种实现方法: