领域驱动设计概念总结

编程

Eric Evans 在2003年出版《驱动设计" title="领域驱动设计">领域驱动设计-软件核心复杂性应对之道》,提出了DDD的软件业务架构划分方法论,成为如今微服务拆分的理论指导,而后Vaughn Vernon出版了《实现领域驱动设计》,以及后续极客时间、gitchat都有这方面的文章,不过都偏于理论,目前还未听闻完全贯彻DDD思想的开源项目,一般都是以C#和Java作为案例。DDD并不想MVC一样,大部分人都能划分的非常明确,且相同。在我看来每个人理解DDD,结合实际项目都会根据技术架构、业务架构、领域驱动设计的理解,得出不一样的领域划分。

1. 基本概念

DDD是对面向对象设计的改进,是开发复杂业务逻辑的一种方法。有利于指导应用程序分解为服务,每个微服务都有自己的领域。要灵活应用DDD来进行设计就需要知道他所提出的名词及概念。

1. 1 领域domain、子域和限界上下文

领域:既可以表示为整个业务系统,也可以表示其中的核心域(core domain)或子域。

子域:领域下拆分的部分

限界上下文:子域是问题空间,限界上下文就是答案空间,不同子域在不同领域的含义是不一样的。限界上下问就是给领域划定边界用的。

1.2 领域服务domain service、应用层

应用层:对应开发中的controller或API接口。

领域服务:处理领域的业务逻辑,实现不属于实体或值对象的业务逻辑对象

1.3 聚合aggregate、聚合根 aggregate root、实体entity、值对象value object

聚合:领域中有多个聚合,是一个边界内的领域对象的集群,由根实体和可能一个或多个其他实体和值对象组成,引用聚合必须通过表示

聚合根:应用中有唯一ID的类,根据识别出的聚合,包含实体与值对象。聚合中的对象生命周期都与聚合根一致,比如订单和订单明细,一般是1:n的关系,订单作为聚合根,订单删了,订单明细也挂了~

实体:内部拥有唯一ID,具有相同属性的两个实体仍然是不同的对象

值对象: 实体的属性,或是值集合的对象,拥有相同属性的值对象可以互换,比如值对象是money,由币种和金额组成。相同的币种和金额的money对象是可以对等的对象。

1.5 仓库repository

用来访问持久化聚合根的对象,简单来说就是聚合根层面的CRUD。spring中与数据库相关的类也是以repository结尾的。

1.6 基础设施infrastructure

常用的工具类,底层数据库持久化

1.7 工厂 factory

将聚合根生成的复杂过程放入工厂类中实现

2. 核心思想

领域驱动设计的核心思想明显就是对于领域的划分。领域中的事务也需要考虑

3. Java落地实现

有赞技术https://tech.youzan.com/dddclue/ 有一个相对完整的业务分析过程与落地实现。

有赞对包模块是这样划分的

结合对项目浅显理解,改造包结构为:

  • infrastructure:里面放入了现有对dao层和util
  • repository:save方法传入聚合根,并且无返回值。具体如何将root拆解为vo对数据进行持久化在save中实现。

4. CQRS

CQRS(Command Query Responsibility Segration),命令与查询职责分离,即读写分离,在代码层面把读写分发到不同类中进行处理,读取可以直接与数据库进行交互。这个框架告诉你,即使CRUD也可以搞的很复杂。作为领域驱动设计发展而来的读写分离的技术架构,也有一套基础组成元素

  • command bus:将多个command 分发至对应的command handle中进行处理
  • event source:事件溯源,保留聚合CRUD的历史记录,对于实现设计和监管的功能非常有帮助
  • event bus:事件总线,异步将event写入数据库
  • command handle:处理command
  • query facade:查询门面,将数据包装为DTO,去除冗余属性(如标识位、创建人等)

简化了下读写分离模型,省去event bus这个消息组件。

实现简单的CQRS

现有Axon框架按照DDD思想设计等CQRS框架。

5. 领域驱动设计并不是银弹

目前市面主流方法论有

  • OOA/OOD/OOP 面向对象的分析设计与方法,通常用UML进行建模描述
  • ER建模,即数据驱动开发,根据业务设计数据库表结构进行开发
  • DDD 领域驱动设计
  • 四色建模,由The Open Group制定,在1995年发表TOGAF架构框架。分为四个元素组成(1)时刻-时间段原型(Moment-Interval Archetype)、(2)参与方-地点-物品原型(Part-Place-Thing Archetype)(3)描述原型(Description Archetype)(4)角色原型(Role Archetype)

    国内很少公司会严格遵循领域驱动设计方法论,高学习成本,往往很难得其精髓。实际上往往根据业务和团队情况,使用E-R图、UML、DDD的某些概念,取几种方法论核心部分进行业务架构分析设计。

    主流MVC架构的确做到了视图、业务、数据的解耦,但是其中的VO是贫血模型(只有属性和对象的get、set方法),业务代码的编写也面向过程化。

    领域驱动设计中说道:该模式只适合用于业务足够复杂及多变,若是简单的业务逻辑,强行套用DDD反而会过度设计,造成简单问题复杂化,违背了DDD实际让复杂业务简单化的初衷。

6. 总结

领域驱动设计的优缺点都非常明显。

缺点

  • 学习成本、团队意识要求,需要对业务高度抽象
  • 需要领域专家与技术人员拉通统一领域语言,耗时大,与现在流行的Scrum敏捷开发相背离
  • 业务变化的复杂性,需要识别多变业务进行领域建模,出现“缺乏设计”与“过度设计”

优点

  • 合理的应用方法论,可以对系统进行抽象,解耦
  • 复杂业务分治

如何使用

  1. 首先判断业务是否足够复杂多变,相对稳定建模
  2. 划分领域、限界上线文等基础部件
  3. 合理将子领域分给不同微服务进行开发

    总之,优秀的设计都是经过大量的与业务进行磨合迭代才产生的,如何界定复杂度和领域还是要与领域专家进行交流。

    参考书籍及资料有~《微服务架构设计模式》、《软件架构设计-大型网站技术架构于业务架构融合之道》、领域驱动设计两本神书、我段的思想、有赞的技术博客。

以上是 领域驱动设计概念总结 的全部内容, 来源链接: utcz.com/z/510368.html

回到顶部