容我找个借口先,日常工作太忙,写作略有荒废。一直想聊下领域驱动设计,以下简称DDD,之前也看过一些教程,公司今年两个项目--银行核心和信用卡核心,都深度运用DDD成功落地,有人说DDD挺难理解,在此讲下我的浅薄认知,
争取言简意赅的点明其核心要义。
  先扔出几个名词:Domain领域对象--对照现实中有唯一属性的事物,就像世界上唯一的你,既富且帅还有能改变世界的行为能力;ValueObject值对象--可重复使用的对象,因领域对象而存在,多附着于领域对象上,如快递地址,你我可以共用;
Aggregate聚合--若干难分难舍的领域对象愉快地成为一个歌唱组合;BoundedContext限界上下文--若干志同道合的聚合走到了一起;Aggregate root聚合根--一个聚合中作为老大的Domain,该聚合出入事项都必须经过他办理。
                                                            图1-各种对象的例子
  首先,DDD的核心理念
  领域驱动设计的断句可以为“领域--驱动设计”,即由领域概念来驱动系统设计,和“领域驱动--设计”,即领域驱动本身的设计,我倾向于前者,因为如果引入DDD,其理念应该是贯穿整个系统诞生过程的。
  DDD的核心理念我认为只需领悟三个词:面向对象、分层、隔离
  面向对象,集中体现在Domain领域对象的代码实现上。C++、Java和Python都强调OOP,但这个OOP很大程度上指的编程语法含义,如何将属性和方法形成一个对象,对象间又存在继承、实现等关系,与“面向过程”对应。DDD的面向对象,
是从现实中抽象出实体对象映射为数据库表和领域对象,该领域对象具有属性和方法。比如在对公信贷中,将信贷合同作为一个Domain,它本身就应该具备现实中“合同文本”事物的属性,包括合同ID、合同类型、签订日、甲乙方、合同内容、信
贷产品、到期日...等等,还应该有签订合同、修改合同、作废合同、关联合同...等等动作,并由若干Domain和ValueObject组合为一个聚合对象,若干聚合又可组合为一个限界上下文对象(若干,可能是零个/一个/多个)。这里要额外提一下,
ValueObject与Domain的根本区别就是Domain有唯一ID,此ID映射为现实世界中事物的唯一性。拿我们熟悉的SpringMVC做面向对象对比,与数据表进行映射的PO/Entity不带有任何动作,只有属性和get/set,如果中间过程有需要组装出来的DTO、
BO等也较少带有业务逻辑方法,更多只是为了在ServiceImpl中作为整体操作对象而存在。
  隔离,有两个方面的含义,一是业务逻辑的隔离,一是数据的隔离。业务逻辑的隔离体现在核心业务逻辑的实现都在一个个Domain对象内部,每个核心业务逻辑都具有业务原子特征,若干Domain对象组合为一个聚合,若干聚合成为一个
BoundedContext,若要使用这些功能,只能通过BoundedContext下的“聚合根”或领域对象提供的接口。数据的隔离体现在一个领域对象对应一些数据表,这些数据表的任何操作,只能通过该领域对象内的方法来实现,即形成一个垂直划分的数据
与逻辑结构。借用银行信贷的概念来讲,合同的业务逻辑全部由合同领域对象实现,且只能由合同领域对象操作合同相关的DB表,如果客户相关业务需要更新客户和合同信息,则由客户领域对象更新客户DB表并通过合同领域对象更新合同相关的
DB表。如下图,各数据要保持逻辑上的隔离,各上下文、绿色Domain之间逻辑隔离:
                                                            图2-各领域对象的全景实例
 
  分层,还是拿我们熟悉的SpringMVC做对比,通常是DAO操作数据库,Service引用DAO,Controller层引用Service来对前端或对外提供业务服务,逻辑的具体实现都大量堆积在ServiceImpl中。DDD将数据库表的CRUD单独作为Repository层,
简称Repo仓储层,Domain中调用Repo的CRUD完成对DB的操作,同时这里有个非常重要的分层原则,即同层之间是严格禁止相互调用的,只能上层调用下层且不能跨层。在Domain层之上是DomainService层,再上是Application层,甚至还有防
腐层等等。在分层上,我认为可以灵活处理,适当裁剪,如DAO层中使用Mybatis,再套上一层成为Repo层,也不失为一种好的实践,做好最为关键的Repo和Domain分层即可。
                                                            图3-DDD分层调用
 
 

图4-SpringMVC与DDD对比

图5-DDD项目包结构实例

  其次,DDD解决了什么问题。解决了领域对象Domain从无到有,领域划分的难题,类似于微服务如何划分的问题,并完成了概念模型到代码的映射。DDD引入了一系列的概念和模型,从理论上支撑了各种DDD对象的设计,并提出了多条核心
原则。当我们面对一个全新的系统建设项目时,就可以先从现实世界中的事物对象开始,整理出各种属性和动作,再将属性和动作按照亲和关系,抽象为领域对象或者值对象,并建立数据表,然后逐步建立起聚合、聚合根、限界上下文对象、领域
服务、应用服务、接口服务等,代码就像聚沙成塔一样,逐层组装为完整的系统代码。
 
 

图6-一种实现DDD结构的方法论

  最后,DDD与微服务的联系。微服务是一种大的架构思想,将关联的功能聚合为一个服务体,多个服务体逻辑上又提供一个系统的完整功能,微服务架构强调的是服务间的隔离与服务规模化后的治理,每个微服务自带数据库独立向外提供特定功
能,多个服务的治理又需要配合网关、缓存中心、消息队列、事务管理器、配置中心、服务容器、容器编排等中间件或平台,共同构成完善的微服务架构,微服务关注层级到服务体为止,强调哪些功能应该组合形成一个服务体,服务体间还可以是异
构的。DDD关注代码从无到有,逐步将“Domain领域对象”概念落实到代码中来,从领域对象到限界上下文,每个限界上下文又可以独立为一个微服务体,也可以是系统代码中的一个Module,DDD不关注整体应用架构,而是代码形成的过程,在代码层
面关注隔离与分层。所以,两者侧重不同,但我认为DDD可以作为微服务架构的前序,一个小处着眼,一个大处着手,结合起来即成了一个非常完整的架构落地方案了。
  全文完,感谢阅读。
 
本人原创,谢绝任何形式转载,否则追究法律责任。
 
    • 我的微信公众号,只写原创文章!
 

白话领域驱动设计DDD的更多相关文章

  1. 领域驱动设计(DDD)

    领域驱动设计(DDD)实现之路 2004年,当Eric Evans的那本<领域驱动设计——软件核心复杂性应对之道>(后文简称<领域驱动设计>)出版时,我还在念高中,接触到领域驱 ...

  2. 领域驱动设计(DDD:Domain-Driven Design)

    领域驱动设计(DDD:Domain-Driven Design) Eric Evans的"Domain-Driven Design领域驱动设计"简称DDD,Evans DDD是一套 ...

  3. python 全栈开发,Day116(可迭代对象,type创建动态类,偏函数,面向对象的封装,获取外键数据,组合搜索,领域驱动设计(DDD))

    昨日内容回顾 1. 三个类 ChangeList,封装列表页面需要的所有数据. StarkConfig,生成URL和视图对应关系 + 默认配置 AdminSite,用于保存 数据库类 和 处理该类的对 ...

  4. 关于领域驱动设计 DDD(Domain-Driven Design)

    以下旨在 理解DDD. 1.     什么是领域? 妈妈好是做母婴新零售的产品,应该属于电商平台,那么电商平台就是一个领域. 同一个领域的系统都有相同的核心业务. eg: 电商领域都有:商品浏览.购物 ...

  5. 基于领域驱动设计(DDD)超轻量级快速开发架构(二)动态linq查询的实现方式

    -之动态查询,查询逻辑封装复用 基于领域驱动设计(DDD)超轻量级快速开发架构详细介绍请看 https://www.cnblogs.com/neozhu/p/13174234.html 需求 配合Ea ...

  6. 轻量级领域驱动设计DDD Lite在嵌入式系统重构中的应用

    前言 目前,关于领域驱动设计(Domain Driven Design)DDD的培训,材料,视频都比较多,大家对DDD的一些概念都有所了解,但是在实际使用过程中,有很多的问题.例如 为什么DDD的架构 ...

  7. 分享我对领域驱动设计(DDD)的学习成果

    本文内容提要: 1. 领域驱动设计之领域模型 2. 为什么建立一个领域模型是重要的 3. 领域通用语言(Ubiquitous Language) 4.将领域模型转换为代码实现的最佳实践 5. 领域建模 ...

  8. 领域驱动设计(DDD)实现之路

    2004年,当Eric Evans的那本<领域驱动设计——软件核心复杂性应对之道>(后文简称<领域驱动设计>)出版时,我还在念高中,接触到领域驱动设计(DDD)已经是8年后的事 ...

  9. 领域驱动设计(DDD:Domain-Driven Design) 介绍

    Eric Evans的“Domain-Driven Design领域驱动设计”简称DDD,Evans DDD是一套综合软件系统分析和设计的面向对象建模方法,本站Jdon.com是国内公开最早讨论DDD ...

  10. 我对领域驱动设计(DDD)的学习成果

    领域驱动设计之领域模型 2004年Eric Evans发表Domain-Driven Design – Tackling Complexity in the Heart of Software (领域 ...

随机推荐

  1. Qt数据可视化项目

    一.创建项目(步骤按常规来即可) 二.ui设计界面 控件的使用 默认视角:Label标签和horizontalSlider标签 水平旋转:Label标签和horizontalSlider标签 垂直旋转 ...

  2. Springcloud 开始来了解

    为什么要学习springcloud? "微服务 "一词源于Martin Fowler 的名为 Microservices 的博文,简单地说, 微服务是系统架构上的一种设计风格, 它 ...

  3. harbor改造为https---血泪史

  4. [音视频处理] FFmpeg使用指北1-视频解码

    本文将详细介绍如何使用ffmpeg 4.4在C++中解码多种格式的媒体文件,这些媒体文件可以是视频.视频流.图片,或是桌面截屏或USB摄像头的实时图片.解码文件后,还将每帧图片转换为OpenCV的Ma ...

  5. flutter 的 in_app_web_view实现下载功能

    flutter与前端交互,利用in_app_web_view实现下载功能: 首先下载库,终端输入 flutter pub add flutter_inappwebview 之后导出 import 'p ...

  6. 将HTML网页转换为Markdown格式的工具及方法

    保存博客文章 早期在markdown语法还没有推出来之前,编写blog是在网页上或olw写的,也就是文章是保存在对方的主机上. 最近计划把我在博客园的一些早期html文章转换成markdown的文件, ...

  7. 前端Vue分享菜单按钮弹框、微博分享、QQ分享、微信好友、朋友圈

    前端Vue分享菜单按钮弹框.微博分享.QQ分享.微信好友.朋友圈 , 下载完整代码请访问uni-app插件市场址:https://ext.dcloud.net.cn/plugin?id=13085 效 ...

  8. C# Collections

    1. Generic 1.1 List<T> No need to say this is the most commonly used data structure in C# coll ...

  9. 除了参数,ref关键字还可以用在什么地方?

    <老生常谈:值类型 V.S. 引用类型>中花了很大的篇幅介绍ref参数针对值类型和引用类型变量的传递.在C#中,除了方法的ref参数,我们还有很多使用ref关键字传递引用/地址的场景,本篇 ...

  10. P7561[JOISC 2021 Day2] 道路の建設案 (Road Construction) 题解

    P7561[JOISC 2021 Day2] 道路の建設案 (Road Construction) 题解 题目描述 JOI 国是一个 \(x\times y\) 的二维平面,王国里有 \(n\) 个城 ...