可落地的DDD(5)-战术设计

 

摘要

本篇是DDD的战术篇,也就是关于领域事件、领域对象、聚合根、实体、值对象的讨论。也是DDD系列的完结篇。
这一部分在我们团队争论最多的,也有很多月经贴,比如对资源库的操作应该放在领域服务还是领域对象中。
聚合根应不应该暴露给外部,还是要转成DTO。这些问题我们讨论了大半年,最后大家基本达成了共识,在当前的业务规模下,
这些问题没那么重要,可东可西。不会对代码的质量有啥大的影响。关于DDD的实践,与团队的水平、业务复杂度息息相关。我们的经验并不一定就适用你们团队。我将战术篇的这么多的内容放在了一篇文章中,并且大部分都是引用之前的讨论、总结。
原因还是在于我内心深处并没有觉得战术篇的实践给我们团队带来多么大的改变。战略篇的是我认为更重要的。

DDD系列文章断断续续也有十来篇了,主要是总结我们团队落地过程遇到的问题和解决方案,算是DDD从学习到落地实践的一个完整的闭环链路,希望对你有所启发。当然这个过程受益最大的肯定是我本人。系统性的思考问题、总结问题、阐述问题是非常有助于提升个人思维能力,朋友们你们也可以尝试一下。

建模

DDD的出现,是大家对于事务性编程,面向数据库表编程的一个反思,明明软件设计是一个面向对象的设计,需要考虑对象之间的继承、多态、组合。
为什么到实际编码过程中成了过程性的编程,为什么对象只有属性没有方法了,也就是失血模型。

关于这几种编程的详细介绍可以参考Martin的《Patterns of Enterprise Application Architecture》Page110

所以我个人觉得,DDD的作用有两个,一个是面向业务的,帮助分析业务模型,进行业务建模。另外一个是面向解决域,即代码落地。
即使用一个规范能够反映对象之间的关系,即OO编程。

目前对DDD研究主要有以下类别

  1. 关于业务分析层面,如何进行概念层面的抽象和设计的方法论
  2. 关于服务划分、代码分层、职责定义的方法论
  3. DDD框架的讨论,比如jdon

第3点基本上没怎么广泛的讨论。我认为未来也不会出现什么牛逼的DDD框架能够流行起来。DDD是一种建模方法,是针对不同的业务领域的,
在不同的团队有不同的落地方案,是没办法靠一种框架来约束,来把一件不统一的事情来统一起来。就好比我们面向对象的设计针对问题域,抽象出来了
20多种设计模式。这些设计模式都是指导思想,你不能搞出一种框架,来约束大家使用某种设计模式就基于这种框架扩展,以此来达到代码统一或者降低
编程难度的目的。

前面的文章主要是比较大的方面,比较适合做整体业务分析。也就是第一个点。今天主要讨论第二点。

OO 编程

DDD的代码分层、职责定义本质上就是OO编程。OO的三大基本要素就是继承、多态、组合。这三个是深度抽象的结果。没法指导具体的编程。
于是我们有了设计模式,前辈们针对问题域,总结除了24种设计模式,这样遇到类似的问题时,我们可以使用对应的设计模式去解决问题。
而这些设计模式底层使用到还是继承、多态、组合。

那有了设计模式了,为什么还要DDD呢?为什么很少看到开源软件用DDD呢?
个人的理解DDD还是面向企业应用架构的,是在众多不确定的业务,系统中提炼出来的一套规范,这样必然是高度抽象的。而开源软件大多是领域比较确定的,比如数据库领域,中间件领域。解决这类问题的系统架构通常会更加复杂以及具有扩展性。

DDD的工程架构网上有很多,我在之前的文章也提到过,这里不再赘述,看下老马的这个,我觉得非常清晰的展现出来了职责分离
https://martinfowler.com/articles/microservice-testing/#conclusion-summary

我们重点看领域一层。
领域包含3点

领域服务

领域对象与领域服务

领域对象

敢于聚合根的激烈讨论

领域事件

CQRS能解什么问题

基础设施层

为各层提供资源服务(如数据库、缓存等),实现各层的解耦,降低外部资源变化对业务逻辑的影响。

总结

战术设计DDD的更多相关文章

  1. DDD(领域驱动设计)--战术设计

    前言 战术设计 战略设计为我们提供一种高层视野来审视我们的软件系统,主要包括领域/子域.通用语言.限界上下文和架构风格等概念, 而战术设计则将战略设计进行具体化和细节化,它主要关注的是技术层面的实施, ...

  2. 可落地的DDD(7)-战术设计上的一些误区

    背景 几年前我总结过DDD战术设计的一些落地经验可落地的DDD(5)-战术设计,和一次关于聚合根的激烈讨论最近两年有些新的落地体验,回过头来发现,当初对这些概念的理解还是没有深入,这篇文章重新阐述下. ...

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

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

  4. 领域驱动设计(DDD)

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

  5. 后端开发实践系列之二——领域驱动设计(DDD)编码实践

    Martin Fowler在<企业应用架构模式>一书中写道: I found this(business logic) a curious term because there are f ...

  6. 领域驱动设计(DDD)编码实践

    写在前面 Martin Fowler在<企业应用架构模式>一书中写道: I found this(business logic) a curious term because there ...

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

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

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

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

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

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

随机推荐

  1. html5文件夹上传源码

    前段时间做视频上传业务,通过网页上传视频到服务器. 视频大小 小则几十M,大则 1G+,以一般的HTTP请求发送数据的方式的话,会遇到的问题:1,文件过大,超出服务端的请求大小限制:2,请求时间过长, ...

  2. 开启php的PDO扩展,mysql扩展

    打开php.ini配置文件,找到extension=php_pdo.dll 和 extension=php_pdo_mysql.dll ,去掉前面“;”的注释,修改后的两行配置内容如下: extens ...

  3. python生成二维码(简易)

    首先要的配置: pillow image qrcode zxing 然后直接上代码: import PIL import qrcode # 实例化二维码生成类 qr = qrcode.QRCode( ...

  4. ansible 错误记录(1)

    基本环境:docker基于centos7 在docker里面安装ansible 不管是在root还是普通用户下执行 ansible all -m ping  都报如下错误: 172.20.1.1 | ...

  5. Lucene4.2源码解析之fdt和fdx文件的读写(续)——fdx文件存储一个个的Block,每个Block管理着一批Chunk,通过docID读取到document需要完成Segment、Block、Chunk、document四级查询,引入了LZ4算法对fdt的chunk docs进行了实时压缩/解压

    2       索引读取阶段 当希望通过一个DocId得到Doc的全部内容,那么就需要对fdx/fdt文件进行读操作了.具体的代码在CompressingStoredFieldsReader类里面.与 ...

  6. mac使用xposed超详细入门级教程Android Studio-20190930

    工具 这里我使用的工具是Android Studio3.4.1,电脑环境mac os mojave 10.14.6(这个应该问题不大) 创建项目 1.打开Android Studio,看到这个界面,并 ...

  7. Java 交换两数的方法

    错误示范 1. 直接交换 public class SwapNumbers { // 直接交换 public static void swap(int a, int b) { int temp = a ...

  8. php手记之05-tp5软删除

    01-需要在设置软删除的模型里设置

  9. Flutter移动电商实战 --(40)路由_Fluro的全局注入和使用方法

    路由注册到顶层,使每个页面都可以使用,注册到顶层就需要在main.dart中 main.dart注册路由 注入 onGenerateRoute是MaterialApp自带的路由配置项, 首页跳转到详细 ...

  10. 【转】nodejs获取post请求发送的formData数据

    前端post请求发送formData的类型数据时,需要服务端引入中间件body-parser,主要原因是post请求发送的数据,是在http的body里面,所以需要进行解析,否则获取不到数据(数据为空 ...