DDD领域驱动设计
文章目录限界上下文DDD的一些定义设计领域模型的一般步骤:根据需求划分出初步的领域和限界上下文,以及上下文之间的关系;进一步分析每个上下文内部,识别出哪些是实习,哪些是值对象;对实体、值对象进行关联和聚合,划分出聚合的范畴和聚合根;为聚合根设计仓储,并思考实体或值对象的创建方式;在工程中实践领域模型,并在实践中检验模型的合理性,倒推模型中不足的地方并重构。现实世界中,领域包含了问题域和解系统。在
设计领域模型的一般步骤:
- 根据需求划分出初步的领域和限界上下文,以及上下文之间的关系;
- 进一步分析每个上下文内部,识别出哪些是实习,哪些是值对象;
- 对实体、值对象进行关联和聚合,划分出聚合的范畴和聚合根;
- 为聚合根设计仓储,并思考实体或值对象的创建方式;
- 在工程中实践领域模型,并在实践中检验模型的合理性,倒推模型中不足的地方并重构。
现实世界中,领域包含了问题域和解系统。在DDD中,解系统可以映射为一个个限界上下文,限界上下文就是软件对于问题域的一个特定的、有限的解决方案。
模块Module是DDD中明确提到的一种控制限界上下文的手段,在工程中一般尽量用一个模块来表示一个领域的限界上下文。
一般的工程中,包的组织方式为:{com.公司名.组织架构.业务.上下文.},这样的组织结构能够明确地将一个上下文限定在包的内部*。
对于模块内的组织结构,一般是按照领域对象、领域服务、领域资源库、防腐层等组织方式定义。
有以下几种情况会考虑引入防腐层:
- 需要将外部上下文中的模型翻译成为当前上下文理解的模型。
- 不同上下文之间的团队协作关系,如果是供奉者关系,建议引入防腐层,避免外部上下文变化对本上下文的侵蚀。
- 该访问本上下文使用广泛,为了避免改动影响范围过大。
限界上下文
一个由显示边界限定的特定职责。领域模型便存在于这个边界之内。在边界内,每一个模型概念,包括它的属性和操作,都具有特殊的含义。
划分限界上下文:
- 考虑产品所讲的通用语言,从中提取一些术语称之为概念对象,寻找对象之间的联系;
- 或者从需求里提取一些动词,观察动词和对象之间的关系;
- 将紧耦合的各自圈在一起,观察他们内在的联系,从而形成对应的限界上下文;
- 形成之后,可以尝试用语言来描述界限上下文的职责,看它是否清晰、准确、简洁和完成;
- 简而言之,限界上下文应该从需求出发,按领域划分。
限界上下文之间的映射关系:
明确限制了限界上下文的耦合性,无论是上下文内部交互还是与外部上下文交互,耦合度都限定在数据耦合(Data Coupling)的层级。
- 合作关系ParnetShip:两个上下文紧密合作的关系;
- 共享内核SharedKernel:两个上下文依赖部分共享的模型;
- 客户方-供应方开发Cunsomer-Supplier Development:上下文之间有组织的上下游依赖;
- 尊奉者Conformist:下游上下文只能盲目依赖上游上下文;
- 防腐层Anticorruption Layer:一个上下文通过一些适配和转换与另一个上下文交互;
- 开放主机服务Open Host Service:定义一种协议来让其他上下文来对本上下文进行访问;
- 发布语言Published Language:通常与OHS一起使用,用于定义开放主机的协议;
- 大泥球Big Ball of Mud:混杂在一起的上下文关系,边界不清晰;
- 另谋他路SeparateWay:两个完全没有任何联系的上下文;
上下文集成:通常集成上下文的手段有多种,常见的手段包括开放领域服务接口、开放HTTP服务以及消息发布-订阅机制。
DDD的一些定义
-
实体Entity:一个对象由其标识(而不是属性)区分。在实践上建议将属性的验证放到实体中。
-
值对象Value Object:一个对象用于对事务进行描述而没有唯一标识。具有不变形、相等性、可替换性。在实践中,需要保证值对象创建后就不能被修改,即不允许外部再修改其属性。在不同上下文集成时,会出现模型概念的公用。
-
聚合根Aggregate Root:聚合是一组相关对象的集合,作为一个整体被外界访问。聚合根是这个聚合的根节点。核心领域往往都需要用聚合来表达。聚合在技术上可以知道详细设计。聚合由根实体、值对象和实体组成。
创建好的聚合:
- 边界内的内容具有一致性:在一个事务中只修改一个聚合实例。如果你发现边界内很难接受强一致,不管是出于性能或产品需求的考虑,应该考虑剥离出独立的聚合,采用最终一致的方式。
- 设计小聚合:大部分的聚合都可以只包含根实体,而无需包含其他实体。即使一定要包含,可以考虑将其创建为值对象。
- 通过唯一标识来引用其他聚合或实体:当存在对象之间的关联时,建议引用其唯一标识而非引用其整体对象。如果是外部上下文中的实体,引用其唯一标识或将需要的属性构造值对象。 如果聚合创建复杂,推荐使用工厂方法来屏蔽内部复杂的创建逻辑。
聚合内部多个组成对象的关系可以用来指导数据库创建,但不可避免存在一定的抗阻。如聚合中存在List<值对象>,那么在数据库中建立1:N的关联需要将值对象单独建表,此时是有id的,建议不要将该id暴露到资源库外部,对外隐蔽。
-
领域服务:一些重要的领域行为或操作。既不是实体,也不是值对象的范畴。当采用了微服务架构风格,一切领域逻辑的对外暴露均需要通过领域服务来进行。
-
领域事件:对领域内发生的活动进行建模。
更多推荐


所有评论(0)