提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档

文章目录

  • 前言
  • 一、DDD是什么?
  • 二、术语介绍
    • 1.DDD中的模型
    • 2.DDD模型的生命周期
    • 3.DDD模型的边界
    • 4.DDD设计的特点
  • 总结

前言

2023/6/8/9:34

实习的时候leader交给我的项目是采用DDD思想,按他的意思是上一个接手这项目的写的模块很多不符合DDD规范,所以希望我能符合DDD规范,因此先进行系统性学习。


提示:以下是本篇文章正文内容,下面案例可供参考

一、DDD是什么?

领域驱动设计(英语:Domain-driven design,缩写 DDD)是一种通过将实现连接到持续进化的模型来满足复杂需求的软件开发方法。领域驱动设计的前提是:
把项目的主要重点放在核心领域(core domain)和域逻辑
把复杂的设计放在有界域(bounded context)的模型上
发起一个创造性的合作之间的技术和域界专家以迭代地完善的概念模式,解决特定领域的问题
领域驱动设计是一种由域模型(墙裂推荐@阿白 的域模型系列)来驱动着系统设计的思想,不是通过存储数据词典(DB表字段、ES Mapper字段等等)来驱动系统设计。领域模型是对业务模型的抽象,DDD是把业务模型翻译成系统架构设计的一种方式。
——引自知乎

二、术语介绍

1.DDD中的模型

Model与传统的POJO(DTO、DO、DAO)类等对比,都是一个类中有属性、属性有Get/Set方法,并且做传输对象。

复习一下:
POJO:“Plain Old Java Object”“简单java对象”。POJO的内在含义是指那些没有从任何类继承、也没有实现任何接口,更没有被其它框架侵入的java对象。主要是Java的开发者被EJB的繁杂搞怕了,大家经过反思,又回归“纯洁老式”的JavaBean,即有无参构造函数,每个字段都有getter和setter的java类。
PO:PO是指持久对象(persistant object持久对象)。持久对象实际上必须对应数据库中的entity(与数据库中的字段一致)
VO:VO是指值对象或者View对象(Value Object、View Object)。View Object。

Model与传统MVC三层架构层的业务逻辑层中的Service对比,都是处理业务行为(Action)层。
模型(Model)承载着业务的属性和具体的行为,是业务表达的方式、是DDD的内核。是一个类中有属性、属性有Get/Set方法,并且业务的行为(Action)操作也是在模型类中(充血模型)即做业务逻辑处理,又做数据传输对象,模型分为Entity、Value Object、Service这三种类型。

1.Entity (实体)
有特定的标识,标识着这个Model在系统中全局唯一
内部值可以是变化的,可能存在生命周期 (比如订单对象,状态值是连续变化的)
有状态的Value Object

2.Value Object (值对象)
内部值是不变的,不存在生命周期 (比如地址对象不存在生命周期)
无状态对象

3.Service (服务)
无状态对象
当一个属性或行为放在Entity、Value Object中模棱两可或不合适的时候就需要以Service的形式来呈现

三种模型的复杂度是不一样的,在领域建模选Model模棱两可时,优先选择简单模型原则。模型复杂度顺序 Service > Entity > ValueObject

2.DDD模型的生命周期

1.Factory (工厂)
用来创建Model,以及帮助Repository (数据源)注入到Model中

2.Aggreagte (聚合根)
封装Model,一个Mode中l可能包含其他Model(类似一个对象中包含其他对象的引用,实际概念更为复杂些)

3.Repository (数据源)
数据源的访问网关层、通过Repository来对接不同的数据源

3.DDD模型的边界

1.限界上下文,领域边界上下文
域的拆分
按业务抽象进行划分
一个业务拆分成几个独立的域,每个域又可细拆成不同子域

2.防腐
一个域在访问其他域的模型时,把获取到的模型做层转换映射到自己域的模型中(不直接使用别的域模型作为自己域模型中的一部分)
防止源域模型发生变更,依赖源域模型的调用方,在需要源域模型新功能时,必须要全局依赖修改,才在能兼容
防止域上下文不一致产生的冲突

4.DDD设计的特点

根据业务模型设计系统
不是通过数据库等数据源驱动设计,是根据业务语义抽象梳理设计成领域模型

数据模型统一
通过真实业务背景,梳理出业务域模型自然会形成出参、入参、中间临时属性收口统一为域模型

业务模型与数据源无关
数据源数据结构无论怎么变、数据源无论怎么换,领域模型统一无感知,无须变更。
一个域模型底层对应的数据源可以是1个或n个不同类型数据源
系统升级底层数据源结构改造时,变更对业务层是透明,域模型可无缝对接,可达到开着飞机换引擎的效果
业务属性字段命名统一、引用唯一
在现在MVC模式开发中,入参model、数据传输model、数据源model 同一个业务属性含义可能有多种不同的命名,引用情况很难直接排除,当丰富某个业务字段值时,很难直接判断对原有业务的影响范围

业务行为Action收口
在原有开发模式下,一个Model类是一个POJO、DTO、DO,仅做数据传输,没有任何业务相关Action,属于典型的贫血模型。在DDD中一个Model就表述一个业务的域(可能是子域),这个Model不仅有属性,还有业务行为Action,并且这个域的所有操作都在这个Model中,这个Model不仅是数据传输的作用也是一个具体的Service,是属于充血模型。开发人员可以通过关注这个域模型就可以cover负责领域的全部,更不会出现大量的复制-粘贴重复代码。

业务操作高内聚、低耦合
所有这个域的操作都内聚在这个Model中,不会存在同一个相同业务行为在多个Service中存在现象。很多时候一个业务行为功能变更,在原有开发模式下需要把所有的service中有这个业务行为的地方都要变更(粘贴复制代码更为严重)

系统更能直观体现业务逻辑
产品是一直在演进的,PRD、技术方案都很难准确的表明现在产品的真实逻辑,很多时候大家都会遇见这种现象,产品经理不确定当前某个业务点的准确逻辑,需要开发阅读代码翻译给产品经理业务逻辑。

铁打的代码、流水的产研,产品经理、开发流动性都很大,新人仅看文档cover整个系统,很难做到。每个业务准确的细节点,还是要看系统代码实际的逻辑规则。

领域驱动架构
领域驱动设计没有特定的架构风格,它的核心是域模型驱动业务的思想,常见的领域驱动设计架构有经典的三层架构、REST架构、事件驱动架构、CQRS架构、六边形架构等。

领域驱动三层架构
API层
API层是作为对外打包、前端接口调用使用。Domian层是整个域模型,不能直接把它打包成maven给别人使用,也不能直接把它作为接口给前端使用,有些需要API层作为进行转换后调用Domain,对调用Domain返回的数据进行包装筛选后再返回出去。

Domain层
系统的核心层,所有具体的业务逻辑处理、事件处理等都在这层域模型中处理

Repository 层
数据源代理层,Repository 层类似一个网关代理,它本身没有数据,数据都是通过它的代理来被Domain层访问,被代理的数据源不仅仅可以是DB、ES还可以是HTTP、RPC任何与Domain层进行数据交互的都叫Repository


总结

领域驱动设计优势和劣势
DDD不是银弹,它只是复杂性业务的一种解决方式。DDD解决了系统设计的‘复杂性’,DDD设计思想本身又存在复杂性。

优势
系统演进更方便
随着业务的变化、系统设计也要演进升级。好的架构设计一定演化来的,不是一开始就设计出来的,但系统演进过程中的成本,一定是最开始的设计决定的。一个健康公司的成长,业务横向、纵向会发展的会越来越复杂,支持业务的系统也一定会越来越复杂。在领域驱动设计中,域模型对应的是业务模型,是系统架构的内核,通过域模型来驱动与外界的交互。

业务复杂性变化的演进

域模型可能是简单新增属性或action就能支撑整体的业务发展。企业订餐的业务系统要同时有用户端、运营端、企业端、商户端的数据展示和操作,当业务演进出一个新功能时,这四端系统可能都要同时改造支撑。在领域驱动中,系统的域模型是同一套,只需在领域层进行改造,即可同时支撑四端。

业务数据量变化的演进

公司业务数据量的变化后,现有的架构往往很难支持业务的发展,一定会进行新的技术选型支持业务。在DDD中,域模型为内核,在内核外的一层是代理层,通过这层代理来抽象透明化掉业务模型对系统底层设计的感知。比如原本数据量很小,一个简单的搜索直接使用MySQL like 模糊查询即可满足,在数据量巨大这种方式无法满足的时候,需要使用ES这种专业的搜索技术来实现,这时候仅需要在数据源层把原本指向数据源MySQL改成ES即可,业务代码全程透明无感知,可以达到给正在飞行的飞机换引擎的效果。

更方便测试
对于测试(包含开发自测)来说,流程跑不通是痛苦的,由于IO造成阻塞而非系统逻辑是更痛苦。测试的时候最喜欢的纯函数测试,不依赖任何IO(不包含机器内存层面),DDD设计思想是天然的在代码上把纯函数和普通函数区分开,Repository层是非纯函数,在Repository层Mock掉,整体系统就成了纯函数系统,对测试在Mock数据、切换数据源是非常方便和友好的。

劣势
系统改造成DDD复杂
我们常用的架构基本都是MVC三层架构方式,在常用的MVC三层架构中基本所有的业务逻辑都在service层中,并且是按service功能属性设计的Service层,现在要进行DDD思想开发,需要打破原有的设计,有些严重的还必需要进行重构设计。

团队开发熟悉DDD思想困难
改变自己比较困难,对别人产生影响更加困难。一个开发团队如果之前对DDD都没有了解,要推进和对团队产生影响是一个艰难的过程。

最后
DDD不仅是统一语言、以业务驱动系统设计,在熟悉新业务和系统重构时,领域驱动设计思想更能很好快速梳理业务。如下图领域驱动设计是以领域(业务模型)为核心,通过数据代理层(Repository)来与其他系统交互,来驱动整个系统架构设计。

领域驱动设计(英语:Domain-driven design,缩写 DDD)相关推荐

  1. 实施领域驱动设计(Implementing Domain Driven Design翻译)

    实施领域驱动设计(Implementing Domain Driven Design翻译) 引言 介绍 这是实现领域驱动的实用指南设计(DDD).虽然实现细节依赖于ABP 框架基础设施,但是核心概念. ...

  2. 初探领域驱动设计(Domain Driven Design)

    前言: 我个人在学习DDD的过程中,早期翻找各种资料的时候,看到了很多名词:战略设计.战术设计.聚合根.实体.值对象.界限上下文...这些繁多的名词定义配合上几乎少的可怜的实战例子,让我在翻阅了大量资 ...

  3. 领域模型驱动设计(Domain Driven Design)入门概述

    软件开发要干什么: 反映真实世界要自动化的业务流程 解决现实问题 领域Domain Domain特指软件关注的领域 在不能充分了解业务领域的情况下是不可能做出一个好的软件 领域建模 领域模型驱动设计 ...

  4. [.NET领域驱动设计实战系列]专题八:DDD案例:网上书店分布式消息队列和分布式缓存的实现...

    原文:[.NET领域驱动设计实战系列]专题八:DDD案例:网上书店分布式消息队列和分布式缓存的实现 一.引言 在上一专题中,商家发货和用户确认收货功能引入了消息队列来实现的,引入消息队列的好处可以保证 ...

  5. DDD领域驱动设计(DP、Entity介绍;DDD实现流程;DDD聚合Aggregate;限界上下文(Bounded Context))

    DDD(Domain Driven Design) DP(Domain Primitive) define: 一切模型.方法.架构的基础,是指在特定领域.拥有精准定义.可以自我验证.拥有行为的对象,可 ...

  6. ddd java repository_初探领域驱动设计(2)Repository在DDD中的应用

    概述 上一篇我们算是粗略的介绍了一下DDD,我们提到了实体.值类型和领域服务,也稍微讲到了DDD中的分层结构.但这只能算是一个很简单的介绍,并且我们在上篇的末尾还留下了一些问题,其中大家讨论比较多的, ...

  7. 领域驱动开发(domain driven development)

    链接: https://www.zhihu.com/question/56332619/answer/250971065 什么是领域驱动开发 将问题抽象为一个领域解决方案.并针对此领域(即抽象)进行开 ...

  8. 领域驱动设计,为何死灰复燃?

    作者简介 张逸,曾先后就职于中兴通讯.惠普 GDCC.中软国际.ThoughtWorks 等大型中外企业,任职角色为高级软件工程师.架构师.技术总监.首席咨询师. 一.领域驱动设计为何又死灰复燃焕发青 ...

  9. 如何系统学习领域驱动设计?

    一.领域驱动设计为何又焕发青春? 领域驱动设计(Domain Driven Design,DDD)确实已不再青春,从 Eric Evans 出版了划时代的著作<领域驱动设计>至今,已有将近 ...

  10. 领域驱动设计最佳实践

    领域驱动设计(Domain Driven Design,DDD)自诞生以来已有十几年时间,这门本已步入老年的方法学却因为微服务的兴起而焕发了第二春.并不是微服务拯救了领域驱动设计,是因为领域驱动设计一 ...

最新文章

  1. Flask入门学习---Hello,Flask!
  2. Python数据结构与算法(第六天)
  3. linux网络基础设置
  4. 软件工程启程篇章:C#和四则运算生成与运算
  5. s6 android 7.0 国行,三星S6电信版/S6 Edge国行版升级安卓7.0
  6. 上海纳税百强2016,邢台2017纳税百强,深圳百强企业
  7. maven引用公共包_使用github作为maven仓库存放发布自己的jar包依赖 实现多个项目公共部分代码的集中,避免团队中多个项目之间代码的复制粘贴...
  8. 使用NPOI——C#和WEB API导出到Excel
  9. python入门三:文件操作
  10. python的作用域分别有几种_Python中作用域的深入讲解
  11. 简述malloc/free与new/delete的区别
  12. 汇川500et变频器源码,说明书,解析文档等
  13. MySQL数据库增删改查(基础操作命令详解)
  14. 主成分分析(PCA)原理、步骤
  15. 鸿蒙系统如何开启快捷方式,鸿蒙系统功能介绍-华为鸿蒙系统功能详细介绍 - 系统家园...
  16. FMI人工智能与大数据线下沙龙第869期北京场圆满落幕
  17. 如何在Windows中轻松查看最近修改的文件
  18. CCS Uniflash烧写CC3200开发板的简易操作笔记
  19. Java时间格式化工具类大全_二
  20. Redis升级到 6.x 版本后,12306网站起飞了!

热门文章

  1. H5页面audio多声音解决方法
  2. python 建站需求_玩转Django2.0---Django笔记建站基础十一(一)(音乐网站开发)
  3. Jeecg-多表联合查询
  4. 比尔·盖茨的 33 年及名言集锦 - 为比尔送行、鼓掌!
  5. 经典游戏“大富翁4”存档文件修改器Rich4Editor下载
  6. scala 时间,时间格式转换
  7. 如何更新Eclipse版本
  8. Java 内嵌的Derby数据库基本使用
  9. 那些编程语言中的“后浪”都怎么样了:Swift 成功把“前浪”拍在沙滩上
  10. 鬼 谷 子 --常读之