容我找个借口先,日常工作太忙,写作略有荒废。一直想聊下领域驱动设计,以下简称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. [MAUI程序设计] 用Handler实现自定义跨平台控件

    @ 目录 Handler 与Xamarin.Forms实现的区别 为什么要用Handler代替Renderer 解耦 生命周期管理 更细粒度的控制 用Effect来实现呢? 自定义手势监听控件 在各平 ...

  2. ISIS 综合实验;BGP 实验

    目录 ISIS 综合实验 实验拓扑 实验需求 实验步骤 1.配置相应接口IP地址及环回口地址 2.配置 IS-IS,要求全网互通,R8的Loop X口暂不宣告 3. R1和R3直连,要求 R3 成为 ...

  3. Hive执行计划之hive依赖及权限查询和常见使用场景

    目录 概述 1.explain dependency的查询与使用 2.借助explain dependency解决一些常见问题 2.1.识别看似等价的SQL代码实际上是不等价的: 2.2 通过expl ...

  4. JS工具函数

    工具函数 用于工程化开发,记录,备用 返回 [min, max) 间的随机整数 /** 返回 [min, max) 间的随机整数 */ export function getRandom(min, m ...

  5. 全面的ASP.NET Core Blazor简介和快速入门

    前言 因为咱们的MongoDB入门到实战教程Web端准备使用Blazor来作为前端展示UI,本篇文章主要是介绍Blazor是一个怎样的Web UI框架,其优势和特点在哪?并带你快速入门上手ASP.NE ...

  6. C++面试八股文:了解auto关键字吗?

    某日二师兄参加XXX科技公司的C++工程师开发岗位第15面: 面试官:了解auto关键字吗? 二师兄:嗯,了解一些(我很熟悉). 面试官:说一说auto的用法吧? 二师兄:auto主要是为了编译器进行 ...

  7. 【HarmonyOS】关于 Caused by java.lang.IllegalStateException The specified...

    [问题描述] 线上收到大量手机的崩溃异常,以华为手机为主,崩溃如下 1.Caused by: java.lang.IllegalStateException: The specified messag ...

  8. 多个视频文件合成画中画效果(Python、ffmpeg)

    Step 1 从视频中分离出音频(MP4->mp3) def separateMp4ToMp3(tmp): mp4 = tmp.replace('.tmp', '.mp4') print('-- ...

  9. 万字长文解析最常见的数据库恢复算法: ARIES

    万字长文解析最常见的数据库恢复算法: ARIES 首发地址: https://mp.weixin.qq.com/s/Kc13g8OHK1h_f7eMlnl4Aw Introduction 上图中为基于 ...

  10. prometheus描点原理

    大家好,我是蓝胖子,关于prometheus的入门教程有很多,拿我之前学prometheus的经历来讲,看了很多教程,还是会对prometheus的描点以及背后的统计原理感到迷惑,所以今天我们就来分析 ...