1.书籍信息
封面 | ![]() |
---|---|
书名 | 《领域驱动设计(Thoughtworks洞见)》 |
作者 | ThoughtWorks中国 |
状态 | 已读完 |
简介 | 当敏捷宣言的17位签署者在2001年喊出“响应变化胜于遵循计划”这样的口号时,鲜有组织会真正把这句话当回事儿,甚至很多经验丰富的管理者会认为好的计划是成功的一半,遵循计划就是另外一半。然而在时下的第四次工业革命浪潮中,可能很多管理者已经不会简单满足于“响应”,而是选择主动发起变化了。不确定性管理成了这个时代的主旋律,企业的响应力成了成败的关键。图的底层是各种数据存储(从经典的Oracle到大数据标配的Hadoop),图的中间是类似Kafka这样的消息管道和传统的ESB(消息总线),上层则是各种业务应用(包括各种Web应用和移动的APP)。仿佛这是一个流行的“稳定”架构设计。 |
资源 |
2.书摘
领域驱动设计(Thoughtworks洞见)
ThoughtWorks中国
33个想法
◆ 什么是架构设计?
假设我们产生了一个团队都达成共识的架构设计,大家都兢兢业业把设计变成了现实。一个长期困扰软件行业的问题出现了,需求总是在变化,无论预先设计如何“精确”,总是发现下一个坑就在不远处。相信很多技术人员都有这样的经历,结果往往是情况越来越糟糕,也就是我们常说的架构腐化了,最后大家不得不接受重写。这些经历让我们逐步明确了软件架构设计的实质是让系统能够更快地响应外界业务的变化,并且使得系统能够持续演进。在遇到变化时不需要从头开始,保证实现成本得到有效控制
◆ 打造架构响应力的方法
领域驱动设计方法DDD(Domain Driven Design)为我们提供了很好的切入点。这个2003年就总结出来的方法终于在10多年后重新走入了架构师的视野,而这一次大家已经意识到了这种方法在这个快速变化时代的重要性。DDD通过以下两个模式去有效解决了文章开始提到的两大痛点:
1.让团队中各个角色(从业务到开发测试)都能够采用统一的架构语言,从而避免组件划分过程中的边界错位。
2.让业务架构和系统架构形成绑定关系,从而建立针对业务变化的高响应力架构。
这两点是DDD的核心,也是为什么时下全球架构圈在进一步向DDD这个方向靠拢的原因。DDD明确了业务和系统架构上的绑定关系,并提供了一套元语言来帮助各个角色有效交流架构设计。

◆ 限界上下文的意义
如果我们再追溯到DDD的战略设计,我们会发现在问题域上,DDD通过子问题域(subdomain)的划分就已经进行了针对业务能力的分解,而限界上下文在解决方案域中完成了进一步分解。当然我们不能完全认为子问题域和限界上下文有严格意义上的一对一关系,但大多数情况下一个子问题域是会被设计成一个或多个限界上下文的。子域subdomain和限界上下文某种意义上是互相印证的,重点在区分问题域和解决方案域,这是落地DDD最困难的地方,也是判断一个架构师能力进阶的分水岭。
◆ 分层架构
DDD方法提出后的数年里,分层架构的具体实现也经历了几代演进,直到Martin Fowler提炼出下图的分层实现架构后,才逐步为大家所认可。DDD的方法也得到了有效的补充,模型落地的问题也变得更容易,核心领域模型的范围也做出了比较明确的定义:包括了Domain,Service Layer和Repositories。

(Martin Fowler总结提出的分层架构实现,注意“Resources”是基于RESTful架构的抽象,我们也可以理解为更通用的针对外界的接口Interface。而HTTP Client主要是针对互联网的通信协议,Gateways实际才是交换过程中组装信息的逻辑所在。)
我们的核心实体(Entity)和值对象(Value Object)应该在Domain层,定义的领域服务(Domain Service)在Service Layer,而针对实体和值对象的存储和查询逻辑都应该在Repositories层。值得注意的是,不要把Entity的属性和行为分离到Domain和Service两层中去实现,即所谓的贫血模型,事实证明这样的实现方式会造成很大的维护问题。DDD战术建模中的元模型定义不应该在实现过程中被改变,作为元模型中元素之一的实体本身就应该包含针对自身的行为定义。
◆ 测试实现
测试驱动开发TDD无疑是一种好的实践,如果应用得当,它确实能够实现我们上述的原则,并且能够帮助我们交流业务的需求。比较有意思的是,在基于DDD建立的核心模型之上应用TDD似乎更加顺理成章。类比DDD和TDD虽然是不恰当的,但我们会发现两者在遵循的原则上是一致的,即都是面向业务做分解和设计:DDD就整个业务问题域进行了分解,形成子问题域;TDD就业务需求在实现时进行任务分解,从简单场景到复杂场景逐步通过测试驱动出实现。下面的测试用例展现了在核心模型上的TDD过程
◆ DDD的终极大招——By Experience
方法Event Storming(ES)
◆ 跨领域合作
当然如果真有经验丰富的领域专家,确实事情就简单了很多。业务问题的分解首先就变得非常流畅,ES的功效也就不那么明显了。然而我个人始终认为“团队共同的学习 胜于 建模本身的正确性”,即使专家也不能完全预见未来,所以团队能够有机会通过某种手段学习专家的知识,也是很有价值的一件事情。
◆ Subdomain和Bounded Context的对应关系?
Subdomain和Bounded Context的对应关系?
探讨了Subdomain的必要性,自然我们需要分析和解决方案这边Bounded Context分解的关系。第一次看Eric构建的DDD模型脑图(如下)时,我一直认为少画了Subdomain和Bounded Context的对应关系。最早采用DDD时,个人认知是一个Subdomain下应该有多个Bounded Context,即当我们分析出了一个子问题后在针对建模的解决方案进行分解,成为多个Bounded Context。所以Subdomain:Bounded Context应该是1:N的关系。

(Eric构建的DDD模型脑图)
然而Vernon一直以来的实践方式隐含着1:1的对应关系。这样的对应关系并非没有道理,如果咱们从一个Bounded Context出发,我们会发现每个Bounded Context必然应该是“解决”部分问题的,而这个部分问题是否就应该是一个Subdomain呢?
当我们拿着这个差异去跟Event Storming的发明者Alberto Brandolini讨论时,发现对方委婉地表达了N:N的理解。简而言之没有直接的对应关系。当然这种理解隐含了一个Bounded Context是可以服务于多个Subdomain子问题的。比如“产品展示”Bounded Context的模型可能服务于产品销售和产品评论两个Subdomain子问题。

这三个对应关系的理解暴露出了大家对问题和解决方案这个老大难问题的纠结~当然最简单的是能够建立一对一的映射,作为解决方案高手的程序员们显然是非常喜欢这个模式的。以至于很多用DDD建模的程序员直接就跳过Subdomain搞起了Bounded Context。当然这也是我坚决反对这样简单化映射关系的重要原因。
出于对方法实操性的考虑,我仍然认为一对多的映射是最优的选择。诚然在我们的现实世界里,问题和解决方案是没有必然对应关系的,他山之石可以攻玉也是古来有之的。但软件设计本身就是一个问题抽象的过程,这个抽象一定会选取一个视角,也就会放弃部分信息。在这样的认知下,其实我并不介意在不同子问题的解决方案里存在一定的重复。
所以,如果让我来站队Subdomain和Bounded Context的对应关系,我仍然会选择一对多。在准确性和易用性之间寻求一个平衡,并保证大家能够更多的关注问题本身。
◆ 1.组织没有领域专家
领域专家应该对问题域及其中的各种可行方案有更深入的理解。在辅导团队的过程中,为了弥补这部分视角的缺失,往往会在事件风暴之前,组织业务愿景和场景分析,与被指派的业务干系人对齐业务愿景,一起分析业务场景背后的问题域,找到问题域的本质后再展开事件风暴。[插图]
◆ 认识领域事件
。一个领域事件必须对业务有价值,有助于形成完整的业务闭环,也即一个领域事件将导致进一步的业务操作。
◆ 事件风暴(Event Storming)
事件风暴是一项团队活动,旨在通过领域事件识别出聚合根,进而划分微服务的限界上下文
◆ 发布领域事件
领域事件产生于领域对象中,或者更准确的说是产生于聚合根中
我们可以采用“在聚合根中临时保存领域事件”的方式予以改进:

在测试Order对象时,我们便你可以通过验证events集合保证Order对象在创建时的确发布了OrderPlacedEvent事件:

在这种方式中,聚合根对领域事件的保存只能是临时的,在对该聚合根操作完成之后,我们应该将领域事件发布出去并及时清空events集合。可以考虑在持久化聚合根时进行这样的操作,在DDD中即为资源库(Repository):

除此之外,还有一种与“临时保存领域事件”相似的做法是“在聚合根方法中直接返回领域事件”,然后在Repository中进行发布。这种方式依然有很好的可测性,并且开发人员不用手动清空先前的事件集合,不过还是得记住在Repository中将事件发布出去。另外,这种方式不适合创建聚合根的场景,因为此时的创建过程既要返回聚合根本身,又要返回领域事件。
这种方式也有不好的地方,比如它要求开发人员在每次更新聚合根时都必须记得清空events集合,忘记这么做将为程序带来严重的bug。不过虽然如此,这依然是笔者比较推荐的方式。
◆ 当提到“事件驱动”时,我们在说什么?
事件通知
状态转移
事件溯源
CQRS
>当提到“事件驱动”时,我们在说什么?
◆ 事件溯源
事件溯源(Event Sourcing)的核心思想是,每当系统状态发生变化时,都将状态更改记录为事件,这样我们就有信心在任何时间都能够通过重新处理事件来重建系统状态。事件库成为事实的主要来源,系统状态完全来源于它。对于程序员来说,最好的例子就是版本控制系统。所有的提交日志就是事件库,源码树的工作副本是系统状态。
◆ 服务于更高的业务响应力
DDD的想法是让我们的软件实现和一个演进的架构模型保持一致,而这个演进的模型来自于我们的业务需求。
◆ 从业务视角分离复杂度
从业务视角分离复杂度每个人能够认知的复杂度都是有限的,在面对高复杂度的时候我们会做关注点分离,这是一个最基本的哲学原则。显然在针对复杂业务场景进行建模时,我们也会应用此原则。这个时候去分离关注点一般可以从两个维度出发:• 技术维度分离,类似MVC这样的分层思想是我们广泛接受的。• 业务维度分离,根据不同的业态划分系统,比如按售前、销售、售后划分。
微服务的架构更强调业务维度的关注点分离来应对高复杂度。
◆ 业务和技术渐进统一的架构设计
“跳过”(或“后补”)业务架构显然表明设计出来的架构关注点并不在业务的响应力上,因为业务的可能变化点并没有被分析出来指导系统和技术架构的设计
DDD的核心诉求就是能够让业务架构和系统架构形成绑定关系,从而当我们去响应业务变化调整业务架构时,系统架构的改变是随之自发的。
往往会推荐用大颗粒度的服务来包含业务分析过程中发现的不确定点,以避免拆分后变化过度频繁带来的双向修改成本。
◆ 跨职能协作的架构设计
DDD成功运用的基础就是创造让业务和系统这两种不同认知模型逐步统一的环境。
所以“不幸”的是如果你不能建立一个跨业务和技术的新型架构设计小组,你的DDD实践就没有成功的基础,继而采用微服务架构可能就会是一场灾难。
◆ 永无终止的DDD和演进的Microservices
良好的领域架构绑定了业务和系统,让双方人员能够用统一语言交流,这件事情建立不易,而持续运作更难。
Microservices的最后一个特质:“演进式”设计–也明确了设计是一种持续的活动。
DDD的好处是让业务和技术人员都能够在合作中理解这种变化,而不至于陷入业务人员抱怨技术架构不知所谓,技术人员觉得业务人员朝三暮四的尴尬。
◆ 你需要成为那个高个子!
在业务需求认知和跨职能协作方面你一定需要成为高个子!
◆ 服务拆分与架构演进
领域驱动设计和服务自演进能力是内功。
◆ 技术组件?不,是业务服务!
服务的设计不只聚焦于当下需求,更需要考虑价值定位和产品愿景。工程团队则需要思考如何用有限成本支撑非线性的业务接入增长。
◆ 第一部分:领域事件的建模
在DDD场景下,领域事件一般随着聚合根状态的更新而产生,另外,在事件的消费方,有时我们希望监听发生在某个聚合根下的所有事件,为此笔者建议为每一个聚合根对象创建相应的事件基类,其中包含聚合根的ID,比如对于订单(Order)类,创建OrderEvent:
◆ 领域驱动设计(DDD)实现之路
赞同
>需要指出的是,DDD绝非一套单纯的技术工具集,但是我所看到的很多程序员却的确是这么认为的,并且也是怀揣着这样的想法来使用DDD的。过于拘泥于技术上的实现将导致DDD-Lite。
◆ 可视化架构设计—C4介绍
从上到下依次是系统System、容器Container、组件Component和代码Code。(咦,那为什么叫C4呢,因为系统的图叫System Context,系统上下文图。为了凑四个C也是够拼的。)基于这四个层次的抽象,C4模型由4张核心图和3张附属图组成,分别用于描述不同的场景
◆ 点评
认为一般
这本书是多人博客文章关于 DDD 部分的大合集
里面的东西良莠不齐,有认为非常赞的,有非常水的
也算是值得一读,但是请跳着读,好的地方仔细品,一般的扫一眼就可以
摘录好的地方如:
DDD 成功运用的基础就是创造让业务和系统这两种不同认知模型逐步统一的环境。
书中有些句子针对有实践经验的人,会比较切点
领域驱动设计(Thoughtworks洞见)
ThoughtWorks中国
33个笔记
什么是架构设计?
假设我们产生了一个团队都达成共识的架构设计,大家都兢兢业业把设计变成了现实。一个长期困扰软件行业的问题出现了,需求总是在变化,无论预先设计如何“精确”,总是发现下一个坑就在不远处。相信很多技术人员都有这样的经历,结果往往是情况越来越糟糕,也就是我们常说的架构腐化了,最后大家不得不接受重写。这些经历让我们逐步明确了软件架构设计的实质是让系统能够更快地响应外界业务的变化,并且使得系统能够持续演进。在遇到变化时不需要从头开始,保证实现成本得到有效控制
打造架构响应力的方法
领域驱动设计方法DDD(Domain Driven Design)为我们提供了很好的切入点。这个2003年就总结出来的方法终于在10多年后重新走入了架构师的视野,而这一次大家已经意识到了这种方法在这个快速变化时代的重要性。DDD通过以下两个模式去有效解决了文章开始提到的两大痛点: 1.让团队中各个角色(从业务到开发测试)都能够采用统一的架构语言,从而避免组件划分过程中的边界错位。 2.让业务架构和系统架构形成绑定关系,从而建立针对业务变化的高响应力架构。 这两点是DDD的核心,也是为什么时下全球架构圈在进一步向DDD这个方向靠拢的原因。DDD明确了业务和系统架构上的绑定关系,并提供了一套元语言来帮助各个角色有效交流架构设计。 
限界上下文的意义
如果我们再追溯到DDD的战略设计,我们会发现在问题域上,DDD通过子问题域(subdomain)的划分就已经进行了针对业务能力的分解,而限界上下文在解决方案域中完成了进一步分解。当然我们不能完全认为子问题域和限界上下文有严格意义上的一对一关系,但大多数情况下一个子问题域是会被设计成一个或多个限界上下文的。子域subdomain和限界上下文某种意义上是互相印证的,重点在区分问题域和解决方案域,这是落地DDD最困难的地方,也是判断一个架构师能力进阶的分水岭。
分层架构
DDD方法提出后的数年里,分层架构的具体实现也经历了几代演进,直到Martin Fowler提炼出下图的分层实现架构后,才逐步为大家所认可。DDD的方法也得到了有效的补充,模型落地的问题也变得更容易,核心领域模型的范围也做出了比较明确的定义:包括了Domain,Service Layer和Repositories。  (Martin Fowler总结提出的分层架构实现,注意“Resources”是基于RESTful架构的抽象,我们也可以理解为更通用的针对外界的接口Interface。而HTTP Client主要是针对互联网的通信协议,Gateways实际才是交换过程中组装信息的逻辑所在。) 我们的核心实体(Entity)和值对象(Value Object)应该在Domain层,定义的领域服务(Domain Service)在Service Layer,而针对实体和值对象的存储和查询逻辑都应该在Repositories层。值得注意的是,不要把Entity的属性和行为分离到Domain和Service两层中去实现,即所谓的贫血模型,事实证明这样的实现方式会造成很大的维护问题。DDD战术建模中的元模型定义不应该在实现过程中被改变,作为元模型中元素之一的实体本身就应该包含针对自身的行为定义。
测试实现
测试驱动开发TDD无疑是一种好的实践,如果应用得当,它确实能够实现我们上述的原则,并且能够帮助我们交流业务的需求。比较有意思的是,在基于DDD建立的核心模型之上应用TDD似乎更加顺理成章。类比DDD和TDD虽然是不恰当的,但我们会发现两者在遵循的原则上是一致的,即都是面向业务做分解和设计:DDD就整个业务问题域进行了分解,形成子问题域;TDD就业务需求在实现时进行任务分解,从简单场景到复杂场景逐步通过测试驱动出实现。下面的测试用例展现了在核心模型上的TDD过程
DDD的终极大招——By Experience
方法Event Storming(ES)
跨领域合作
当然如果真有经验丰富的领域专家,确实事情就简单了很多。业务问题的分解首先就变得非常流畅,ES的功效也就不那么明显了。然而我个人始终认为“团队共同的学习 胜于 建模本身的正确性”,即使专家也不能完全预见未来,所以团队能够有机会通过某种手段学习专家的知识,也是很有价值的一件事情。
Subdomain和Bounded Context的对应关系?
Subdomain和Bounded Context的对应关系? 探讨了Subdomain的必要性,自然我们需要分析和解决方案这边Bounded Context分解的关系。第一次看Eric构建的DDD模型脑图(如下)时,我一直认为少画了Subdomain和Bounded Context的对应关系。最早采用DDD时,个人认知是一个Subdomain下应该有多个Bounded Context,即当我们分析出了一个子问题后在针对建模的解决方案进行分解,成为多个Bounded Context。所以Subdomain:Bounded Context应该是1:N的关系。  (Eric构建的DDD模型脑图) 然而Vernon一直以来的实践方式隐含着1:1的对应关系。这样的对应关系并非没有道理,如果咱们从一个Bounded Context出发,我们会发现每个Bounded Context必然应该是“解决”部分问题的,而这个部分问题是否就应该是一个Subdomain呢? 当我们拿着这个差异去跟Event Storming的发明者Alberto Brandolini讨论时,发现对方委婉地表达了N:N的理解。简而言之没有直接的对应关系。当然这种理解隐含了一个Bounded Context是可以服务于多个Subdomain子问题的。比如“产品展示”Bounded Context的模型可能服务于产品销售和产品评论两个Subdomain子问题。  这三个对应关系的理解暴露出了大家对问题和解决方案这个老大难问题的纠结~当然最简单的是能够建立一对一的映射,作为解决方案高手的程序员们显然是非常喜欢这个模式的。以至于很多用DDD建模的程序员直接就跳过Subdomain搞起了Bounded Context。当然这也是我坚决反对这样简单化映射关系的重要原因。 出于对方法实操性的考虑,我仍然认为一对多的映射是最优的选择。诚然在我们的现实世界里,问题和解决方案是没有必然对应关系的,他山之石可以攻玉也是古来有之的。但软件设计本身就是一个问题抽象的过程,这个抽象一定会选取一个视角,也就会放弃部分信息。在这样的认知下,其实我并不介意在不同子问题的解决方案里存在一定的重复。 所以,如果让我来站队Subdomain和Bounded Context的对应关系,我仍然会选择一对多。在准确性和易用性之间寻求一个平衡,并保证大家能够更多的关注问题本身。
1.组织没有领域专家
领域专家应该对问题域及其中的各种可行方案有更深入的理解。在辅导团队的过程中,为了弥补这部分视角的缺失,往往会在事件风暴之前,组织业务愿景和场景分析,与被指派的业务干系人对齐业务愿景,一起分析业务场景背后的问题域,找到问题域的本质后再展开事件风暴。[插图]
认识领域事件
。一个领域事件必须对业务有价值,有助于形成完整的业务闭环,也即一个领域事件将导致进一步的业务操作。
事件风暴(Event Storming)
事件风暴是一项团队活动,旨在通过领域事件识别出聚合根,进而划分微服务的限界上下文
发布领域事件
领域事件产生于领域对象中,或者更准确的说是产生于聚合根中
我们可以采用“在聚合根中临时保存领域事件”的方式予以改进:  在测试Order对象时,我们便你可以通过验证events集合保证Order对象在创建时的确发布了OrderPlacedEvent事件:  在这种方式中,聚合根对领域事件的保存只能是临时的,在对该聚合根操作完成之后,我们应该将领域事件发布出去并及时清空events集合。可以考虑在持久化聚合根时进行这样的操作,在DDD中即为资源库(Repository):  除此之外,还有一种与“临时保存领域事件”相似的做法是“在聚合根方法中直接返回领域事件”,然后在Repository中进行发布。这种方式依然有很好的可测性,并且开发人员不用手动清空先前的事件集合,不过还是得记住在Repository中将事件发布出去。另外,这种方式不适合创建聚合根的场景,因为此时的创建过程既要返回聚合根本身,又要返回领域事件。 这种方式也有不好的地方,比如它要求开发人员在每次更新聚合根时都必须记得清空events集合,忘记这么做将为程序带来严重的bug。不过虽然如此,这依然是笔者比较推荐的方式。
当提到“事件驱动”时,我们在说什么?
事件通知 状态转移 事件溯源 CQRS
当提到“事件驱动”时,我们在说什么?
事件溯源
事件溯源(Event Sourcing)的核心思想是,每当系统状态发生变化时,都将状态更改记录为事件,这样我们就有信心在任何时间都能够通过重新处理事件来重建系统状态。事件库成为事实的主要来源,系统状态完全来源于它。对于程序员来说,最好的例子就是版本控制系统。所有的提交日志就是事件库,源码树的工作副本是系统状态。
服务于更高的业务响应力
DDD的想法是让我们的软件实现和一个演进的架构模型保持一致,而这个演进的模型来自于我们的业务需求。
从业务视角分离复杂度
从业务视角分离复杂度每个人能够认知的复杂度都是有限的,在面对高复杂度的时候我们会做关注点分离,这是一个最基本的哲学原则。显然在针对复杂业务场景进行建模时,我们也会应用此原则。这个时候去分离关注点一般可以从两个维度出发:• 技术维度分离,类似MVC这样的分层思想是我们广泛接受的。• 业务维度分离,根据不同的业态划分系统,比如按售前、销售、售后划分。
微服务的架构更强调业务维度的关注点分离来应对高复杂度。
业务和技术渐进统一的架构设计
“跳过”(或“后补”)业务架构显然表明设计出来的架构关注点并不在业务的响应力上,因为业务的可能变化点并没有被分析出来指导系统和技术架构的设计
DDD的核心诉求就是能够让业务架构和系统架构形成绑定关系,从而当我们去响应业务变化调整业务架构时,系统架构的改变是随之自发的。
往往会推荐用大颗粒度的服务来包含业务分析过程中发现的不确定点,以避免拆分后变化过度频繁带来的双向修改成本。
跨职能协作的架构设计
DDD成功运用的基础就是创造让业务和系统这两种不同认知模型逐步统一的环境。
所以“不幸”的是如果你不能建立一个跨业务和技术的新型架构设计小组,你的DDD实践就没有成功的基础,继而采用微服务架构可能就会是一场灾难。
永无终止的DDD和演进的Microservices
良好的领域架构绑定了业务和系统,让双方人员能够用统一语言交流,这件事情建立不易,而持续运作更难。
Microservices的最后一个特质:“演进式”设计–也明确了设计是一种持续的活动。
DDD的好处是让业务和技术人员都能够在合作中理解这种变化,而不至于陷入业务人员抱怨技术架构不知所谓,技术人员觉得业务人员朝三暮四的尴尬。
你需要成为那个高个子!
在业务需求认知和跨职能协作方面你一定需要成为高个子!
服务拆分与架构演进
领域驱动设计和服务自演进能力是内功。
技术组件?不,是业务服务!
服务的设计不只聚焦于当下需求,更需要考虑价值定位和产品愿景。工程团队则需要思考如何用有限成本支撑非线性的业务接入增长。
第一部分:领域事件的建模
在DDD场景下,领域事件一般随着聚合根状态的更新而产生,另外,在事件的消费方,有时我们希望监听发生在某个聚合根下的所有事件,为此笔者建议为每一个聚合根对象创建相应的事件基类,其中包含聚合根的ID,比如对于订单(Order)类,创建OrderEvent:
领域驱动设计(DDD)实现之路
赞同
需要指出的是,DDD绝非一套单纯的技术工具集,但是我所看到的很多程序员却的确是这么认为的,并且也是怀揣着这样的想法来使用DDD的。过于拘泥于技术上的实现将导致DDD-Lite。
可视化架构设计—C4介绍
从上到下依次是系统System、容器Container、组件Component和代码Code。(咦,那为什么叫C4呢,因为系统的图叫System Context,系统上下文图。为了凑四个C也是够拼的。)基于这四个层次的抽象,C4模型由4张核心图和3张附属图组成,分别用于描述不同的场景
微信读书
3.读后感 & 点评
认为一般
这本书是多人博客文章关于 DDD 部分的大合集 里面的东西良莠不齐,有认为非常赞的,有非常水的 也算是值得一读,但是请跳着读,好的地方仔细品,一般的扫一眼就可以 摘录好的地方如: DDD 成功运用的基础就是创造让业务和系统这两种不同认知模型逐步统一的环境。 书中有些句子针对有实践经验的人,会比较切点