DDD 领域驱动设计简述

Wesley13
• 阅读 1016

目录

文章目录

  • 目录
  • 传统分层架构存在的问题
  • 领域驱动设计
  • 领域驱动设计思想
  • 领域驱动设计面临的问题

传统分层架构存在的问题

DDD 领域驱动设计简述

传统的分层架构会在 Service 层、Manager 层实现具体的业务逻辑,使用 DO、DTO、BO、VO 等进行数据传输,数据和行为基本完全隔离。

  • Service 层:相对具体的业务逻辑服务层。
  • Manager 层:通用业务处理层,具有有如下特征:
    • 对第三方平台封装的层,预处理返回结果及转化异常信息。
    • 对 Service 层通用能力的下沉,如:缓存方案、中间件通用处理。
    • 与 DAO 层交互,对多个 DAO 的组合复用。

这样的分层架构存在一个问题:因为分层采用的是包的形式进行的层间隔离,所以需要每一位开发人员都理解并且自觉遵守以上规范,但是在实际工作中因为开发人员对 Service 层和 Manager 层的区别并不特别清楚,或难以完全遵守手册中的规范,就导致 Manager 层除了沉底一些通用能力以外和 Service 层并没有什么本质区别。在实际的业务代码中 Service 层和 Manager 层都充斥了大量的第三方依赖,对系统的稳定性有很大的影响。每依赖一个第三方服务都要各种异常问题,这些异常处理的代码往往会和业务代码混在一起,当这种代码多了以后会使代码的可读性非常差。随着业务迭代速度也很快, Service 层和 Manager 层代码量迅速膨胀,业务逻辑变得越来越复杂。

领域驱动设计

领域驱动设计的概念是 2004 年 Evic Evans 在他的著作《Domain-Driven Design : Tackling Complexity in the Heart of Software》(领域驱动设计:软件核心复杂性应对之道)中提出的。

领域驱动设计是一套方法论,指导我们将复杂问题进行拆分、拆分出各个子系统间的关联以及是如何运转的,帮助我们解决大型的复杂系统在落地中遇到的问题。简而言之,DDD 是一个分而治之的过程,是一系列分而治之的方法论

Evic Evans 在著作中将软件系统的设计分为 2 个部分:

  1. 战略设计:提出了域、子域、限界上下文等重要概念,指导我们如何拆分一个复杂的系统。
  2. 战术设计:提出了实体、值对象、领域服务、领域事件、聚合、工厂、资源库等重要概念,指导我们对于拆分出来的单个子系统如何进行落地,在落地过程中应该遵循哪些原则。

DDD 领域驱动设计简述

以电子商务系统举例,大型电子商务系统的拆分过程中我们可以把电商系统这个单体应用拆分成:订单子系统、库存子系统、物流子系统、搜索推荐子系统等等。

DDD 在战略层面上的域、子域、限界上下文的划分思想和微服务的划分不谋而合。微服务的划分是也是将一个大的问题拆分成若干个小的问题,每一个小的问题用一个或多个微服务来解决。

  • 域对应一个问题空间,也就是上例中的电商系统;
  • 子域是把域这个大的问题空间拆分成若干个小的更容易解决的问题空间,也就是单体应用向微服务演进过程中划分出来的各个子系统;
  • 限界上下文是解决方案空间,每个子域对应一个或多个解决方案空间。

而 DDD 的战术设计部分就是指导我们如何落地一个系统才可以使系统具备高可扩展性、高可读性。

系统最终都要以代码的形式落地,而落地的工作都是由普通的开发人员来完成,系统是否具备高可扩展性、高可读性直接影响了整个团队的效率。

总结一下,DDD 在软件开发中的主要起到如下作用:

  1. 帮助分析理解复杂业务领域问题,描述业务中涉及的实体及其相互之间的关系,是需求分析的产物,与问题域相关。
  2. 是需求分析人员与用户交流的有力工具,是彼此交流的语言。
  3. 分析如何满足系统功能性需求,指导项目后续的系统设计。

领域驱动设计思想

DDD 的革命性在于其是面向对象分析的方法论,它利用面向对象的特性(封装、多态)有效地化解复杂性,而传统 J2EE 或 SSH 框架等事务性编程模型只关心数据。这些数据对象除了简单的 setter/getter method 外,不包含任何业务逻辑,业务逻辑都是以过程式的代码写在 Service 层中。这种方式极易上手,但随着业务的发展,系统也很容易变得混乱复杂。

DDD 关心的是业务中的领域划分(战略设计)和领域建模(战术设计),其开发过程不再以数据模型(Data Model)为起点,而是以领域模型为出发点,研发过程如下图所示。

DDD 领域驱动设计简述

领域模型对应的是业务实体,在程序中主要表现为类、聚合根和值对象,它更加关注业务语义的显性化表达,而不是数据的存储和数据之间的关系。

领域驱动设计面临的问题

DDD 尚存在一些争议,当前的核心问题是针对软件开发导致软件结构越来越混乱,越来越复杂,越来越难以维护的问题,开出的药方超越了当前众多公司的发展阶段和实操水平。

换句话说,当前大多数互联网企业软件开发经验尚且薄浅,缺乏积累和人才积累,盲目运用 DDD 技术开发,会极大增加开发成本。DDD 对开发者素质要求非常高,甚至达到了专家级要求,主要反映在三个方面:

  1. DDD 的设计和开发成本非常高。首先需要雇佣领域专家和掌握 DDD 设计与开发方法的开发者,在开发之前必须前置领域设计流程,在项目建设工期非常紧张的情况下,DDD 将导致开发效率降低,开发难度增大,开发工作量剧增的问题,不利于项目建设过程中的贯彻和坚持;
  2. DDD 缺乏成熟的 IT 大厂实践、分享和技术支持。目前社区资源不足,开源工程,例如:github/micro-company、github/ddd-leaven-akka-v2 和大型实践项目比较少。了解和掌握 DDD 的软件工程师凤毛麟角、不同公司业务场景各不相同、真正理解垂直市场的领域专家和全面掌握 DDD 设计的专家就更少了;
  3. DDD 的思想范式相对 CRUD、MVC 过于复杂,概念繁多,过于抽象,表述不够清晰,难以理解,不易被初级开发者掌握。DDD 的范式流派目前主要有 EDA、CQRS、Event Sourcing、In-Memory、DCI、CSP 等流派,它们之间互有冲突,不分伯仲,各自从某一个角度出发,解决部分问题,但也引出了其它新问题,例如:数据一致性危机,事务危机和代码复杂度问题,在当前绝大多数公司和业务场景下,必须混合使用,目前尚未出现大一统的理论架构。当前仍缺乏成熟的配套技术以降低开发者学习和运用其的难度和成本。主要体现在缺乏类似 Spring 这种现象级别的成熟框架,允许一个在校生学习一个月就基本可以进行生产级的代码开发工作。当前尚且不够成熟的 DDD 框架 AxonFramework、AKKA 或国产 JdonFramework 等学习成本比较高,不易被缺乏开发经验的工程师快速掌握应用。
点赞
收藏
评论区
推荐文章
blmius blmius
3年前
MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1
文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s
皕杰报表之UUID
​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为
待兔 待兔
4个月前
手写Java HashMap源码
HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程22
Wesley13 Wesley13
3年前
DDD领域驱动设计实战
整洁架构、CQRS、六边形架构等微服务架构都旨在“高内聚低耦合”。那DDD分层架构又如何?1DDD分层架构1.1分层架构的基本原则每层只能与位于其下方的层发生耦合。1.2分层架构的分类严格分层架构(StrictLayersArchitect
Wesley13 Wesley13
3年前
DDD领域驱动设计
C进阶系列——DDD领域驱动设计初探(七):Web层的搭建(https://www.oschina.net/action/GoToLink?urlhttps%3A%2F%2Fwww.cnblogs.com%2Flandeanfen%2Fp%2F4920577.html)C进阶系列——DDD领域驱动设计初探(六):领域服务(https://w
Wesley13 Wesley13
3年前
MySQL部分从库上面因为大量的临时表tmp_table造成慢查询
背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_
Wesley13 Wesley13
3年前
DDD领域驱动设计实战(三)
        点击上方“JavaEdge”,关注公众号设为“星标”,第一时间纵览好文!1前言实体是领域模型中的领域对象。传统开发人员总将关注点放在数据,而非领域。因为在软件开发中,DB一直占据主导,因此首先考虑的是数据的属性(即数据库的列)和关联关系(外键关联),而非富有行为的领域概念
快速理解DDD领域驱动设计架构思想-基础篇 | 京东物流技术团队
1前言本文与大家一起学习并介绍领域驱动设计(DomainDriveDesign)简称DDD,以及为什么我们需要领域驱动设计,它有哪些优缺点,尽量用一些通俗易懂文字来描述讲解领域驱动设计,本篇并不会从深层大论述讲解落地实现,这些大家可以在了解入门后再去深层次
Python进阶者 Python进阶者
10个月前
Excel中这日期老是出来00:00:00,怎么用Pandas把这个去除
大家好,我是皮皮。一、前言前几天在Python白银交流群【上海新年人】问了一个Pandas数据筛选的问题。问题如下:这日期老是出来00:00:00,怎么把这个去除。二、实现过程后来【论草莓如何成为冻干莓】给了一个思路和代码如下:pd.toexcel之前把这
郑文 郑文
7个月前
DDD(领域驱动设计)思想解读及优秀实践
DDD(领域驱动设计)思想解读及优秀实践download》quangneng.com/1964/DDD是什么DDD(DomainDrivenDesign,领域驱动设计)是一种软件开发方法论,它提供了一种方式来设计软件应用程序,以满足复杂需求。该方法将重点放