领域驱动设计(一)理解分层架构
“企业级应用系统”具有复杂的业务,和相对较长的生命周期,在其生命周期中,业务规则将会是经常变化的,所使用的技术也可能发生变更。为了后期能更好的对这类系统进行扩展和维护,我们可以选择面向领域的多层架构,降低组件之间、层与层之间的耦合,这样在每次业务逻辑发生变化或者有新的业务扩展时,我们都能将变化锁定在领域层,从而最大限度的降低对其他层的影响。
领域驱动架构通常分为四层:表示层、应用层、领域层和基础设施层。
表示层(Presentation)
该层的主要职责是通过用户界面向用户显示数据信息,同时解释用户的命令,并把用户的请求发送到应用层。
应用层(Application)
应用层主要用于协调不同领域对象之间的动作或领域模型与基础结构层组件之间的工作,以完成一个特定的、明确的系统任务。
有一个需求是保存一个订单后,需要发送一封Email给用户。保存订单是业务,业务代码在领域层中;而发送Email则应是基础设施层的功能,那么就需要使用应用层来协调领域对象和基础设施对象之间的动作。
领域模型层(Domain Model)
将业务逻辑高度内聚到领域层,所以领域层是整个系统的核心,它只与实际业务相关,不应关心任何技术细节,尽可能的做到与持久化无关。
-
实体
实体在领域模型中非常重要,由标识来区分的对象称为实体(即标识必须唯一)。
-
值对象
和实体不同,值对象没有标识,不需要跟踪值对象的状态,而且值对象非常容易创建和丢弃。值对象是不可变的,用一个构造器创建,所有属性都定义为只读。如果其中一个属性需要修改,那么就需要重新创建一个新的值对象来进行整体替换。值对象的相等性比较是通过各个属性值的比较来完成的。
-
领域层服务
在设计领域模型时,有些业务行为不适合放在任何一个领域对象中,或者该业务行为需要联合多个领域实体才能完成,那么我们就把其放在对应的领域服务中。领域层服务负责和领域中的实体对象、值对象以及其他领域层对象交互。
-
聚合(Aggregate)
聚合通常定义一组关联的对象,以及对象和关系之间的边界,作为一个数据更改的单元处理。每个聚合只有一个聚合根(实体对象)。聚合根可以引用其他聚合根,聚合内的对象可以引用聚合内的另一个对象,但是聚合边界外的任何对象不能绕过聚合根对象访问聚合内的对象。
-
仓储(Repository)
为每一个聚合根对象创建一个仓储,表示该种类型的所有对象为一个概念的对象集合,对仓储的访问通过类似集合的接口。仓储的要点是让开发人员将精力聚焦在领域模型逻辑上,并将真实的数据访问隐藏在仓储接口后面,这就是之前说的领域模型与持久化无关。
-
工厂(Factory)
很多时候,构造一个聚合以及其所有的关系、约束、规则等比较复杂,让一个实体对象自己负责对象的创建就会使得代码变得混乱。此时就需要有一个工厂,能够知道如何构建这些类型的对象,并统一进行创建。
基础设施层(Infrastructure)
基础设施层包含任何类型的框架、数据访问代码或者公共的帮助方法等,是纯技术的一层。