《实现领域驱动设计》拆书稿 DDD 入门 & 领域、子域和限界上下文
第1章:DDD入门
拆书稿
一、为什么我们需要DDD?
使领域专家和开发者在一起工作,这样开发的软件能够准确地传达业务规则。
"准确传达业务规则"意思是说:此时的软件就像是领域专家是编码人员时所开发出来的一样。
可以帮助业务人员自我提高。
确保软件知识并不只是掌握在少数人手中。
在领域专家、开发者和软件本身之间不存在"翻译"。
设计就是代码,代码就是设计。
DDD提供了战略设计和战术设计两种方式。战略设计:帮助我们理解哪些投入是最重要的;哪些既有软件资产是可以重新拿来使用的;哪些人应该被加到团队中?战术设计:帮助我们创建DDD模型中各个部件。
二、DDD是什么?
DDD是一种软件开发方法
DDD将领域专家和开发人员聚集到一起,开发的软件能够反映出领域专家的思维模型。目标是:交付最具业务价值的软件。
DDD关注业务战略:指引我们如何实现面向服务架构(service-oriented architecture)或者业务驱动(business-driven architecture)架构。
使用战术设计建模工具:这些战术设计工具使开发人员能够按照领域专家的思维模型开发软件。保证成功地交付真正的业务价值。
我们平时一些常见的设计问题
贫血症
现象:
你的领域对象包含了太多和业务没有关系的属性。
你的领域对象只是将关系型数据库中的模型映射到了对象上而已。
失忆症
由贫血设计导致的失忆症问:
1、业务意图不明确;
2、方法的实现本身增加了潜在的复杂性;
3、领域对象根本就不是对象,而只是一个数据持有器(data holder);
......
三、如何DDD?
1、理解两大支柱:
通用语言、限界上下文(Bounded Context)
2、如何掌握和建立通用语言?
模型图:同时绘制物理模型图和概念模型图(不正式,区别于UML),并标以名字和行为;
术语表:创建一个包含简单定义的术语表和词组;
共创:找团队的其他成员来检查你的术语表和词组;
四、使用DDD有什么业务价值?
获得了一个非常有用的领域模型
业务得到了更准确的定义和理解
领域专家可以为软件设计做出贡献减少只有少数人才了解模型的情况
更好的用户体验
清晰的模型边界
更好的企业架构
敏捷、迭代式和持续建模
使用战略和战术新工具战术建模工具:聚合(Aggregate)、实体(Entity)、值对象(Value Object)、领域服务(Domain Service)、领域事件(Domain Event)
五、实施DDD所面临的挑战和心理准备
要花费大量时间和精力来思考业务领域,研究概念和术语。
持续地将领域专家引入项目
改变开发中对领域的思考方式
读后思考
1、什么是架构设计?
现在架构师一般工作流程是怎么样的?现在很多架构师和家装公司的相似性;设计了一套架构,无论预先设计如何"精确",发现需求总是在变,前面总是有坑,情况越来越糟,最后不得不重写。
软件架构设计的本质是什么?让系统能够更快地响应外界业务的变化,并且使得系统能够持续演进。在遇到变化时不需要从头开始,保证实现成本得到有效控制。
2、DDD能解决我们什么问题?
原来的架构模式满足不了业务快速变化
原来的架构都是针对技术的,DDD把业务和系统架构绑定在一起来考虑,提高针对业务变化的高响应力。
从业务出发、面向业务变化是我们现代架构设计成功的关键。架构设计的核心实质是保证面对业务变化时我们能够有足够快的响应能力。
团队中各个角色的沟通成本高居不下
在团队中各个角色之间建立通用语言;
同一个团队中(产品、开发、测试)使用同一种架构语言;
不同团队中,可以避免组件划分过程中的边界错位。
3、结合实际项目的思考问题
在目前的团队项目中如何进行DDD?
可能遇到的困难和阻力是什么?
在当前项目或团队中进行DDD,你期望达到的目标和效果是什么?
推荐阅读
第2章:领域、子域和限界上下文
拆书稿
一、什么是领域(Domain)、子域、限界上下文?
领域(Domain)即是一个组织所做的事情以及其中所包含的一切。
子域业务系统的某个方面,我们将这些概念和功能用例如"核心域"、"子域"的名词将他们区分开。
限界上下文将领域模型中的每一个数据都进行限界划分,把它们分别放在不同的上下文边界内。
子域 是一个抽象的概念,是指问题空间。按照解决问题的层面又可以分为:
核心域
支撑子域
通用子域
二、现实世界中领域和子域
领域包含:问题空间(problem space)和 解决方案空间(solution space)
问题空间:是核心域和其他子域的组合
需要思考的问题:
这个战略核心域的名字是什么,它的目标是什么?
这个战略核心域中包含哪些概念?
这个核心域的支撑子域和通用子域是什么?
如何安排项目人员?
你能组建出一支合适的团队吗?
解决方案空间:包括一个或多个限界上下文,即一组特定的软件模型
需要思考的问题:
有哪些软件资产是已经存在的,它们可以重用吗?
三、理解限界上下文
定义说明
限界上下文是一个显示边界,领域模型便存在于边界之内。在边界内,通用语言中的所有术语和词组都有特定的含义,而模型需要准确地反映通用语言。
理解:同一个对象在不同限界上下文中,拥有不同的属性和行为。
例子
图书:对于一个图书出版机构,它需要处理图书生命周期的不同阶段。这些不同的阶段对应于不同的上下文环境,有如下:
概念设计,计划出书
联系作者,签订合同
管理图书的编辑过程
设计图书布局,包括插图
将图书翻译成其他语言
出版纸质版或电子版图书
市场营销
将图书卖给销售商或直接卖给读者
将图书发送给销售商或读者
哪些因素会导致我们创建不正确的限界上下文?
1、从技术层面而不是语义边界来考虑问题使用平台、框架、基础设施或组件影响限界上下文设计
2、根据开发任务的分配来拆分限界上下文不要为了管理技术资源而创建一些假(fake)的上下文边界。模块可以用来拆分开发者的任务职责,我们可以使用更加战术化的手段来管理团队的任务分配。一个团队,一个限界上下文。
读后思考
1、我们的问题空间是什么?它是由哪些战略核心域及其支撑子域组成?
2、团队工作分配和限界上下文如何结合?
将一个团队分配给一个限界上下文在我们公司里可行吗?会遇到哪些问题?
多个团队分配同一个限界上下文会遇到哪些问题?
在实际团队分配中结合限界上下文有没有更好的方式?
3、子域和限界上下文的关系是什么?
子域是问题域,限届上下文是解决方案域,子域的问题通过限界上下文解决。说实话,这个问题确实不好区分,太抽象,得在具体的实际项目中讨论才有意义,而且即使是在同一个项目中,不同人看问题的角度也是不一样的。
4、如何划分限界上下文?
很重要的一个点是要识别并去除二义性。那什么是二义性呢?
举个例子:儿子这个名词,在我家,儿子指的是我那上幼儿园的儿子;但是在我父母家,儿子代表的就是我自己。我家 和 我父母家,就是两个典型的限界上下文,当说"儿子"时,必须明确告知是在哪个家庭的上下文。这就是二义性。
推荐阅读
版权声明: 本文为 InfoQ 作者【三界】的原创文章。
原文链接:【http://xie.infoq.cn/article/adc0ffd04d3ef8892e8d251ce】。文章转载请联系作者。
评论