容我找个借口先,日常工作太忙,写作略有荒废。一直想聊下领域驱动设计,以下简称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. Java中synchronized的优化

    本文介绍为了实现高效并发,虚拟机对 synchronized 做的一系列的锁优化措施 高效并发是从 JDK5 升级到 JDK6 后一项重要的改进项,HotSpot 虚拟机开发团队在 JDK6 这个版本 ...

  2. LLM探索:环境搭建与模型本地部署

    前言 最近一直在炼丹(搞AIGC这块),突然发现业务代码都索然无味了- 上次发了篇AI画图的文章,ChatGPT虽然没法自己部署,但现在开源的LLM还是不少的,只要有一块差不多的显卡,要搞个LLM本地 ...

  3. hadoop 2.7.7 ERROR datanode.DataNode: BlockSender.sendChunks() exception: java.io.IOException: 你的主机中的软件中止了一个已建立的连接。

    最近在测试Hbase在windows上的单机版的功能. 版本:hadoop 2.7.7  hbase 2.0.0 错误: ERROR datanode.DataNode: BlockSender.se ...

  4. 解决echarts图形由于label过长导致文字显示不全问题

    使用echarts 打印饼图,在pc没问题,但一到移动端问题就来了,由于屏幕过小,导致label部分被遮挡 一.问题分析 如上图这个就尴尬了,囧么办呢? 还好echarts 提供了formatter方 ...

  5. 数据库SQL复习

    数据库SQL介绍 Def:SQL是一种极其高效的数据库系统语言:可以实现对数据库中的数据进行增删改查等操作 增加操作:使用create命令: 可以create table 可以create View ...

  6. 简单了解一下国产CPU

    这几天在B站.油管上刷了一些国产芯片真实上手视频,顺便自己也梳理一下芯片的一些基本概念,以及在美国科技制裁和围堵的情况下,国产CPU的发展情况.文末有我整理的一张思维导图,hope u find it ...

  7. Java 实战介绍 Cookie 和 Session 的区别

    HTTP 是一种不保存状态的协议,即无状态协议,HTTP 协议不会保存请求和响应之间的通信状态,协议对于发送过的请求和响应都不会做持久化处理. 无状态协议减少了对服务压力,如果一个服务器需要处理百万级 ...

  8. PostgreSQL 12 文档: 部分 V. 服务器编程

    部分 V. 服务器编程 这部分关于使用用户定义的函数.数据类型.触发器等扩展服务器功能.这些是高级主题,读者应该在理解了有关PostgreSQL的所有其他用户文档之后才阅读这些主题.这一部分的后面一些 ...

  9. 可视化容器管理工具-portainer.io使用

    续docker日常使用指南 背景 当我们开始使用docker后,我们的机器上镜像和容器会越来越多,或者有时候我们有多台开发机的时候,单纯使用命令行去管理镜像和容器就变得麻烦了,这时,我们就可以选择一些 ...

  10. 简约版八股文(day1)

    Java基础 面向对象的三大基本特征 封装:将一些数据和对这些数据的操作封装在一起,形成一个独立的实体.隐藏内部的操作细节,并向外提供一些接口,来暴露对象的功能. 继承:继承是指子类继承父类,子类获得 ...