Skip to main content

DDD理论的核心

背景介绍

tip

张建飞软件教练, 代码精进之路,程序员的底层思维,cola框架 作者

核心理论

DDD本质

  1. 统一语言
  2. 领域建模
  3. 领域边界

核心概念

  1. 领域 特定的知识或者范围
  2. 模型 领域特定的抽象
  3. 上下文 决定词的含义和内涵

统一语言的重要性

  1. 本质
  2. 提高效率
  3. 解决协同沟通问题
  4. 是否有软件产品的领域词汇表
  5. 词汇表和代码能对应上

建模过程

  1. 提取特定的抽象
  2. 考虑上下文
  3. 提取公共业务,循序渐进,沉淀领域能力

eg1:

假如有一个客户管理系统,业务那边发起了一个新的业务规则: 从3月份,注册资本1000万以上的公司被认为是大客户

重构前

场景1:

if registeredCapital >= 1000w {
// do something
}

场景2:

if registeredCapital >= 1000w {
// do something
}

重构后

场景1:

if customer.isBigClient() {
// do something
}

场景2:

if customer.isBigClient() {
// do something
}

Customer {

registeredCapital int64

func isBigClient() {
return registeredCapital >= 1000w
}

}

重构收益

  1. 代码维护性: 只需要修改一处代码,避免散弹式修改

  2. 代码可理解性: 大客户是一个重要的领域知识,业务语义得到显性化的表达,是一种knowledge Rich Design的设计

注:知识丰富的设计(Knowledge Rich Design),怎么理解?,就是通过领域对象(Domain Object),
领域语言(Ubiquitous Language)将核心的领域概念通过代码的形式表达出来,从而增加代码的可理解性。
这里的领域核心不仅仅是业务里的“名词”,所有的业务活动和规则如同实体一样,都需要明确的表达出来。

eg2:

先把App做厚,再把App做薄

第一步:先在里面把完整的业务逻辑表达出来

public class CustomerServiceImpl {

public void register(CustomerDTO customerDTO) {
// 查找 customer
Customer customer = Customer.fromDTO(customerDTO)
// 校验
if customer.getAge() > 18 {
return errors.New("对不起,你未满18")
}
// 查看健康码
HealthCode requset = new HealthCodeRequest();
HealthCodeRes res = healthoCodeSevice.check(request)
if res.isSucess() {
return errors.New("get code err")
}
if !res.isGreen() {
return errors.New("code not greeen")
}
//注册用户
customer.Save(xxx)
}
}

第二步: 沉淀领域能力

对于年龄校验,谁最清楚?当然是customer自己,这是他自己的能力,需要把领域知识沉淀 对于外部域,通过gateway 进行防腐,转义,同样也可以内聚到customer

public class CustomerServiceImpl {

public void register(CustomerDTO customerDTO) {
// 查找 customer
Customer customer = Customer.fromDTO(customerDTO)
// 校验
customer.isRequireAge()
// 查看健康码
customer.isHealthCodeGreen()
//注册用户
customer.Save(xxx)
}
}

微服务相关

  1. 提供了方法论
  2. 边界模型和统一语言是基础

模糊概念

  • 核心域 能赚钱的域
  • 跨多个实体的业务逻辑通过领域服务来实现,跨多个聚合的业务逻辑通过应用来实现。考虑一致性的话通过消息中间件,幂等,重试等分布式中间件保证,聚合内的逻辑可以使用单一数据库事务处理
  • 一次事件只更新一个聚合
  • 事务包裹跨聚合服务编排,应用于实时性和数据一致性比较高的场景
  • 领域事件后可以影响读模型,也可以触发规则策略
  • 实体只包含get/set为失血,包含get/set,原子 为贫血, 包含set/get,原子,组合业务逻辑为充血,包含 set/get, 原子,组合,持久化为胀血
  • 领域最核心
  • CQRS 业务实现读模型可以不经过domain,如果业务逻辑需要更新系统状态变更就必须要在domain层处理

评论区