目录

一、前言

二、DDD是什么?

三、DDD的职责:

复杂系统的应对:

微服务架构:

DDD架构:

四、DDD相关概念:

领域

限界上下文(Bounded Context)

统一语言

五、DDD的实现:

战略建模

内容:

划分限界上下文

限界上下文之间的映射关系(Context Mapping)

战术建模:

内容:

模块(Module):

实体(Entity):

值对象(Value Objects)

聚合(Aggregate)

领域服务(Domain Services)

领域事件(Domain Events)

代码分层架构:

DDD落地应对的挑战:


一、前言

宏观上:

  • 互联网业务发展初期“小步快跑,迭代试错”的情形下要求系统需要快速迭代,但是随着互联网公司逐渐深入实体经济,业务日益复杂,我们在开发中也越来越多地遇到传统行业软件开发中所面临的问题。
  • 传统的研发模式中,系统分析和设计是分开的,导致需求和成品非常容易出现偏差,两者相对独立,还会导致沟通困难。
  • DDD打破了这种隔阂,提出了领域模型概念,统一了分析和设计编程,使得软件能够更灵活快速跟随需求变化。

微观上:

  • Action/Service/DAO这种分层架构下,开发模式通常是面向过程、面向数据的。这种开发模式下,对象只是数据的载体,没有行为。整个开发的过程都是以数据为中心,以数据库ER设计为驱动,面向数据进行开发,即数据驱动设计
  • 业务逻辑都是写在Service中,简单的业务系统采用这种贫血模型和过程化设计是没有问题的,但当业务逻辑复杂了,业务逻辑、状态会散落到在大量方法中,原本的代码意图会渐渐不明确,我们将这种情况称为由贫血症引起的失忆症。
  • 随着业务的不断发展,业务逻辑变得越来越复杂,系统的实现逻辑也变得越来约复杂,最后的结果就是没有人能够描述清楚每个细节,当对现有功能进行迭代时,光回顾该功能涉及的流程(涉及的改动点)就需要很长的时间,而且还容易出现梳理遗漏的情况。
  • 这种情形下,rd往往通过[新写一套逻辑+开关控制]的方式来完成这次的迭代,该功能之后再经历几次迭代后,同一功能在系统中可能存在多个版本的代码,这样就形成恶性循环,每次迭代都需要花费大量的时间去回顾之前多个版本的代码。
  • 最终,当迭代的成本超过了重构的成本,rd就开始对该功能进行重构,重构是克服演进式设计中大杂烩问题的主力,通过在单独的类及方法级别上做一系列小步重构来完成,我们可以很容易重构出一个独立的类来放某些通用的逻辑,但是,重构时会发现你很难给它一个业务上的含义,只能给予一个技术维度描绘的含义。这会带来什么问题呢?新同学并不总是知道对通用逻辑的改动或获取来自该类。显然,制定项目规范并不是好的idea。我们又闻到了代码即将腐败的味道。
  • 更好的做法是采用领域模型的开发方式,将数据和行为封装在一起,并与现实世界中的业务对象相映射。各类具备明确的职责划分,将领域逻辑分散到领域对象中。

其它分享:

  • 数据驱动设计 VS 领域驱动设计:领域驱动设计峰会-领域驱动设计大揭秘

二、DDD是什么?

  • DDD(Domain-Driven Design):领域驱动设计是一套应对复杂软件系统分析和设计的建模方法论。

三、DDD的职责:

复杂系统的应对:

  • 系统的复杂度越来越来高是必然趋势,原因可能来自自身业务的演进,也有可能是技术的创新,然而一个人和团队对复杂性的认知是有极限的,就像一个服务器的性能极限一样,解决的办法只有分而治之,将大问题拆解为小问题,最终突破这种极限,架构设计的4个层面:

    • 业务架构——根据业务需求设计业务模块及其关系 ,关注系统的功能。
    • 系统架构——设计系统和子系统的模块,关注系统的整体性能。
    • 技术架构——决定采用的技术及框架,关注系统的实现方案(框架/缓存/..)
    • 工程架构——代码的分层设计

微服务架构:

  • 应对系统架构、技术架构上的挑战(主要是可用性/性能),通过注册中心、负载均衡、限流、熔断等方案来应对。

DDD架构:

  • 应对业务架构、工程架构上的挑战:通过战略建模和战术建模的方式将业务架构映射到系统架构上,在响应业务变化调整业务架构时,也随之变化系统架构。

四、DDD相关概念:

领域

概念:

  • 业务范围以及在其中所进行的活动称为领域。

分类:

  • 领域可以划分为子域,在领域划分过程中,会不断划分子域,子域按重要程度会被划分成三类:

    • 核心域:核心竞争力,业务成功的主要促成因素。
    • 通用域:不是核心,被整个业务系统使用。
    • 支撑域:不是核心,可以通过购买满足需求。

注意:

  • 在建设一个领域模型时,我们通常只关注核心业务(核心域),而不是试图创建一个全功能的领域模型,因为那样是十分困难的并且还容易导致建模失败。

限界上下文(Bounded Context)

概念:

  • 业务流程的实现方案/业务问题的解决方案(eg:软件系统等)称为限界上下文。

作用:

  • 限界上下文明确了领域模型的边界。

统一语言

  • 定义上下文的含义

  • 价值是可以解决不同角色(RD、PM、QA)间的交流障碍

五、DDD的实现:

战略建模

内容:

  • 于高层次、宏观上去划分和集成限界上下文。

划分限界上下文

  • 每个限界上下文专注于解决某个特定的子域的问题,每个子域都对应一个明确的问题,提供独立的价值,每个子域都相对独立,故各个限界上下文之间也是相对独立的。
  • 同一个概念,不必总是对应于一个单一模型。
    • 子域及其对应的限界上下文中的模型会因为其要解决的问题变化而变化,不会因为其他子域的变化而变化,即低耦合;
    • 当一个子域发生变化时,只需要修改其对应限界上下文中的模型,不需要变动其他子域的模型,即高内聚。

限界上下文之间的映射关系(Context Mapping)

  • 合作关系(Partnership):两个上下文紧密合作的关系,一荣俱荣,一损俱损。
  • 共享内核(Shared Kernel):两个上下文依赖部分共享的模型。
  • 客户方-供应方开发(Customer-Supplier Development):上下文之间有组织的上下游依赖。
  • 遵奉者(Conformist):下游上下文只能盲目依赖上游上下文。
  • 防腐层(Anticorruption Layer):一个上下文通过一些适配和转换与另一个上下文交互。
  • 开放主机服务(Open Host Service):定义一种协议来让其他上下文来对本上下文进行访问。
  • 发布语言(Published Language):通常与OHS一起使用,用于定义开放主机的协议。
  • 大泥球(Big Ball of Mud):混杂在一起的上下文关系,边界不清晰。
  • 另谋他路(SeparateWay):两个完全没有任何联系的上下文。

战术建模:

这篇文章不错:DDD 战术设计

内容:

通过模块、聚合、实体、值对象、领域服务、领域事件等对象来细化限界上下文。

模块(Module):

  • 是一种控制限界上下文的手段,在工程中我们一般使用一个模块来表示一个领域的限界上下文。
  • 一般的工程中包的组织方式为{com.公司名.组织架构.业务.上下文.*},这样的组织结构能够明确的将一个上下文限定在包的内部。

实体(Entity):

  • 当一个对象由其标识(而不是属性)区分时,这种对象称为实体。

值对象(Value Objects)

  • 当一个对象用于对事务进行描述而没有唯一标识时,它被称作值对象。
  • 在实践中,需要保证值对象创建后就不能被修改,即不允许外部再修改其属性

聚合(Aggregate)

  • 聚合是一组相关对象(实体、值对象)的集合,作为一个整体被外界访问,聚合是为了保证领域内对象之间的一致性问题。
  • 如何创建好的聚合?
    • 聚合边界内必须明确有哪些信息,如果没有这些信息就不能称为一个有效的聚合。
    • 设计小聚合:
      • 大部分的聚合都可以只包含根实体(Aggregate Root),而无需包含其他实体。
      • 即使一定要包含,可以考虑将其创建为值对象。
    • 通过唯一标识来引用其他聚合或实体:
      • 当存在对象之间的关联时,建议引用其唯一标识而非引用其整体对象。
      • 如果是外部上下文中的实体,引用其唯一标识或将需要的属性构造值对象。
      • 如果聚合创建复杂,推荐使用工厂方法来屏蔽内部复杂的创建逻辑。
    • 边界内的内容具有一致性:
      • 在一个事务中只修改一个聚合实例。
      • 如果你发现边界内很难接受强一致,不管是出于性能或产品需求的考虑,应该考虑剥离出独立的聚合,采用最终一致的方式。
  • 常见场景:一个主记录对应多条明细记录的场景。
  • 设计方案:
    • 若可以有效控制明细数量,且明细数量较小时,主记录和明细记录可以设计为一个聚合。
    • 若明细数量可能很大时,考虑到性能的问题,我们应该将主记录和明细记录设计为两个聚合,当明细记录更新后发布领域事件,主记录根据明细更新事件做出相应的修改,这样就可以保证主记录和明细记录之间互不依赖。

领域服务(Domain Services)

  • ​​​​​​​业务逻辑优先在聚合根边界内完成;聚合根中不合适放置的业务逻辑才考虑放到 DomainService 中。

领域事件(Domain Events)

  • 领域事件是对领域内发生的活动进行的建模。

代码分层架构:

ddd四层架构

DDD落地应对的挑战:

落地DDD需要应对的挑战

参考:

DDD 模式从天书到实践 - 知乎

领域驱动设计在互联网业务开发中的实践 - 美团技术团队

DDD战术设计,到底如何编码?

DDD-领域驱动设计相关推荐

  1. DDD领域驱动设计之聚合、实体、值对象

    关于具体需求,请看前面的博文:DDD领域驱动设计实践篇之如何提取模型,下面是具体的实体.聚合.值对象的代码,不想多说什么是实体.聚合等概念,相信理论的东西大家已经知晓了.本人对DDD表示好奇,没有在真 ...

  2. DDD领域驱动设计 — 贫血模型与充血模型

    文章转载来源:https://juejin.cn/post/6917125801460629518 | 前言  要想深入掌握和了解 DDD 领域驱动设计的核心,那无论如何也绕不开两大较为抽象的概念-- ...

  3. DDD 领域驱动设计:贫血模型、充血模型的深入解读!

    作者:JavaEdge在掘金 链接:https://juejin.cn/post/6917125801460629518 -     前言     - 要想深入掌握和了解 DDD 领域驱动设计的核心, ...

  4. 浅谈我对DDD领域驱动设计的理解

    从遇到问题开始 当人们要做一个软件系统时,一般总是因为遇到了什么问题,然后希望通过一个软件系统来解决. 比如,我是一家企业,然后我觉得我现在线下销售自己的产品还不够,我希望能够在线上也能销售自己的产品 ...

  5. C#进阶系列——DDD领域驱动设计初探(五):AutoMapper使用

    前言:前篇搭建了下WCF的代码,就提到了DTO的概念,对于为什么要有这么一个DTO的对象,上章可能对于这点不太详尽,在此不厌其烦再来提提它的作用: 从安全上面考虑,领域Model都带有领域业务,让Cl ...

  6. DDD 领域驱动设计:贫血模型、充血模型的深入解读

    点击上方"朱小厮的博客",选择"设为星标" 后台回复"书",获取 后台回复"k8s",可领取k8s资料 -     前言 ...

  7. [转]浅析DDD(领域驱动设计)

    最近在做一些微服务相关的设计,内容包括服务的划分,Restful API的设计等.其中比较棘手的就是Service的职责划分:如何抽象具有统一业务范畴的Model,使其模块化,又如何高度提炼并组合多模 ...

  8. 浅析DDD(领域驱动设计)

    最近在做一些微服务相关的设计,内容包括服务的划分,Restful API的设计等.其中比较棘手的就是Service的职责划分:如何抽象具有统一业务范畴的Model,使其模块化,又如何高度提炼并组合多模 ...

  9. DDD 领域驱动设计落地实践:六步拆解 DDD

    引言 相信通过前面几篇文章的介绍,大家对于 DDD 的相关理论以及实践的套路有了一定的理解,但是理解 DDD 理论和实践手段是一回事,能不能把这些理论知识实际应用到我们实际工作中又是另外一回事,因此本 ...

  10. DDD 领域驱动设计-三个问题思考实体和值对象(续)

    上一篇:DDD 领域驱动设计-三个问题思考实体和值对象 说实话,整理现在这一篇博文的想法,在上一篇发布出来的时候就有了,但到现在才动起笔来,而且写之前又反复读了上一篇博文的内容及评论,然后去收集资料, ...

最新文章

  1. HCNE题库附件、可下载
  2. Java开发和运行环境的搭建(详细教程)
  3. 一键洞悉员工级人效!智邦国际集团业财一体化管理系统:业财一心,基业长青
  4. 入职必备两小时入门SVN(一)
  5. 面向对象的写法,见到就添,持续更新。。。
  6. python选择排序_Python实现选择排序
  7. linux的三大服务器,Linux三大重要事件
  8. er ubnt x设置教程_ubnt的er-x做交换机应该怎么设置啊?
  9. livechart 只显示 y 值_输电铁塔各种截面的回转半径i值特点及其计算
  10. R、Rstudio、Rtools的下载与安装
  11. 博客迁移说明 : )
  12. 青春校园小说:天使会爱上恶魔【完】『看了绝对上瘾』(欢迎转载)
  13. 作为一个精神病人是一种怎样的体验?
  14. 单片机初学者电路常识
  15. 为什么你只需要CD音质:16bits, 44.1kHz的意义
  16. Spring Boot 实现接口的各种参数校验
  17. 爬虫及数据分析--当当网
  18. java图片不失真压缩_(转)图片等比压缩,确保不失真
  19. 全面详解Android实现多线程的几种方式(史上最全,最详细)
  20. usb万能驱动win7_最新电脑为何不支持安装win7系统?原来秘密就藏在这里

热门文章

  1. linux管道操作命令,Linux中可用于管道操作的命令总结
  2. 软件测试工作交接文档模版,软件测试岗位人员离职文档交接
  3. python report_python之reportlab
  4. CS61B+CS170
  5. 深度学习(13):pointnet++论文翻译与学习
  6. 数字供销方案、供销社数字化、信息化
  7. Multisim的学习记录(一)
  8. 高交会|华创芯光邀您一起畅游可见光通信的世界
  9. 三位分节制顺口溜_一位高人写的ISO14001顺口溜,超赞!
  10. 北京房价预测——线性回归