摘要

本篇是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(5)-战术设计的更多相关文章

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

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

  2. 战术设计DDD

    可落地的DDD(5)-战术设计   摘要 本篇是DDD的战术篇,也就是关于领域事件.领域对象.聚合根.实体.值对象的讨论.也是DDD系列的完结篇.这一部分在我们团队争论最多的,也有很多月经贴,比如对资 ...

  3. DDD领域驱动设计落地实践(十分钟看完,半小时落地)

    一.引子 不知今年吹了什么风,忽然DDD领域驱动设计进入大家视野.该思想源于2003年 Eric Evans编写的"Domain-Driven Design领域驱动设计"简称DDD ...

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

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

  5. 可落地的DDD(4)-如何利用DDD进行微服务的划分(2)

    摘要 在前面一篇介绍了如何通过DDD的思想,来调整单体服务内的工程结构,为微服务的拆分做准备.同时介绍了我们在进行微服务拆分的时候踩过的一些坑. 这篇介绍下我们最终的方案,不一定对,欢迎留言讨论. 微 ...

  6. 浅谈我对DDD领域驱动设计的理解

    从遇到问题开始 当人们要做一个软件系统时,一般总是因为遇到了什么问题,然后希望通过一个软件系统来解决. 比如,我是一家企业,然后我觉得我现在线下销售自己的产品还不够,我希望能够在线上也能销售自己的产品 ...

  7. DDD 领域驱动设计-商品建模之路

    最近在做电商业务中,有关商品业务改版的一些东西,后端的架构设计采用现在很流行的微服务,有关微服务的简单概念: 微服务是一种架构风格,一个大型复杂软件应用由一个或多个微服务组成.系统中的各个微服务可被独 ...

  8. (转载)浅谈我对DDD领域驱动设计的理解

    原文地址:http://www.cnblogs.com/netfocus/p/5548025.html 从遇到问题开始 当人们要做一个软件系统时,一般总是因为遇到了什么问题,然后希望通过一个软件系统来 ...

  9. DDD领域驱动设计的理解

    DDD领域驱动设计的理解 从遇到问题开始 当人们要做一个软件系统时,一般总是因为遇到了什么问题,然后希望通过一个软件系统来解决. 比如,我是一家企业,然后我觉得我现在线下销售自己的产品还不够,我希望能 ...

随机推荐

  1. 章节十四、2-自动完成功能-Autocomplete

    一.什么是自动匹配功能? 很多网站都有自动匹配功能,列如你在使用天猫搜索商品时,输入“鞋”,输入框的下面会出现很多与“鞋”有关的选项. 二.以https://www.expedia.com/网站的城市 ...

  2. xshell5运行hadoop集群

    ---恢复内容开始--- 1.CentOS主机配置 在配置Hadoop过程中,防火墙必须优先关闭SELinux,否则将影响后续Hadoop配置与使用,命令如下: # 查看 “系统防火墙” 状态命令 s ...

  3. windows elasticsearch使用ik分词器插件后启动报错java.security.AccessControlException: access denied ("java.io.FilePermission" "D:...........\plugins\ik-analyzer\config\IKAnalyzer.cfg.xml" "read")

    删除es安装文件夹中空格,遂解决......(哭

  4. MySql学习笔记三

    MySql学习笔记三 4.DML(数据操作语言) 插入:insert 修改:update 删除:delete 4.1.插入语句 语法: insert into 表名 (列名1,列名2,...) val ...

  5. pytest生成allure报告

    在pytest框架中可以用很多插件来生成测试报告,本文总结下怎么生成allure报告 allure allure是一款开源的,专门用来展示测试结果的一个工具,allure可以与很多的测试框架做集成,比 ...

  6. Rust中的枚举及模式匹配

    这个enum的用法,比c要强,和GO类似. enum Coin { Penny, Nickel, Dime, Quarter, } fn value_in_cents(coin: Coin) -> ...

  7. python安装thrift-sasl提示缺少sasl.h文件

    这其实是在pip安装Cyrus-SASL bindings for Python时报的错误. 由于没有whl文件,都是源码要经过编译之后才能安装. 所以,报这个错误,一般都是缺少安装软件造成的. 不管 ...

  8. day5_configparser模块

    第一种情况:# 配置文件baidu.ini和当前文件在同一级目录: import configparser conf_read = configparser.ConfigParser() conf_r ...

  9. 调试经验分享-让自己的电脑充当WI-Fi模块,用来抓取连接Wi-Fi模块APP上的通信数据

    需求 手头有了厂家的APP和Wi-Fi模块 在已经知道APP是通过TCP连接Wi-Fi模块(8266), 同时也知道了连接的端口号的 情况下如何知道厂家的APP发送给Wi-Fi模块的数据 打开自己的笔 ...

  10. tornado中命名路由及反向解析使用

    一. 命名路由: 通常路由写法为[ (r'/' , Handler), ... ] 以上路由写法无法实现命名, 使用命名路由需借助tornado提供的方法, 如下: [ tornado.web.url ...