DDD专题之--入门

最近入手一本关于DDD领域驱动设计的书籍,叫做《实现领域驱动设计》。认真拜读,记录每一个章节的学习记录。也希望能帮助到其他正在初学DDD的朋友们。

我能DDD吗?

我很肯定的回答:能!!!。
首先,DDD并不是关于技术的,而是关于讨论、聆听、理解、发现和业务价值的,而这些都是为了将知识集中起来。如果你了解公司的业务,那么你就可以成为DDD中的一员,并作出贡献。
如果你现在愿意将不怎么使用技术语言的人加入进自己的团队,并且愿意聆听他们,向他们学习,他们也向你学习。我可以肯定的告诉你,你已经具备良好的DDD基础了。
如果你发现有人不懂技术,并且比你更好的理解业务知识,找到他们,聆听他们,并向他们学习。

将领域专家引入到团队是大有好处的!
在这里说的领域专家并不是一个职位,他可以是精通业务的任何人。他们可能了解更多的关于业务领域的背景知识,他们可能是软件产品的设计者,甚至有可能是销售员

为什么我们需要DDD

直接说答案不墨迹!!!!
  • 使领域专家和开发者一起工作,这样开发出来的软件能够更准确地传达业务规则。
  • “准确传达业务规则”的意思是说,此时的软件就像领域专家所开发出来的一样
  • 可以帮助业务人员自我提升。没有任何一个领域专家或管理者或开发者敢说他对业务已经了如指掌了,业务知识也需要一个长期的学习过程。在DDD中,每个人都在学习,同时每个人又是业务知识的贡献者。
  • 关键在于对知识的集中,因为这样可以确保软件知识,业务知识并不是掌握在少数人手中。
  • 在领域专家,开发者和软件本身之间不存在翻译,因为大家都在使用相同的语言进行交流,每个人都能听懂其他人在说什么。
  • 设计就是代码,代码就是设计。
  • DDD同时提供了战略设计和战术设计两种方式。战略设计帮助我们理解那些投入是最重要的;哪些既有软件资产是可以重新拿来使用的;哪些人应该被加入到团队中。战术设计则帮追我们创建DDD模型中各个部件。

这就要求DDD过程需要我们在时间和精力都有所投入,来解决软件开发过程中遇到的各种问题和挑战。你会发现这些投入是值得的。

了解DDD需要面临的挑战

领域专家和开发者之间:

通常来说,领域专家将关注点放在了交付业务价值上,而开发者则将注意力放在了编码上。这里并不能说谁对谁错,我想说明的是开发者很自然的被吸引到的代码实现层面。即使让领域专家开开发者一同工作,表面上是协作的工作关系。这时会导致开发者并不能将领域专家的思维模式映射到软件功能上边。随着时间的推移,逐步会增加软件成本

专家和专家之间

当多个领域专家之间存在分歧的时候,这是很有可能发生的。
或者是在某个领域我们没有找到真正的专家,此时,有人可能对该领域有所了解,但是他更像一个业务分析员。这些问题都将导致相互矛盾的软件模型。

软件的技术实现

软件的技术实现可能错误地改变软件的业务规则。比如ERP软件通常需要修改业务欧操作来满足特殊的用户需求,因此ERP的成本不能单纯的使用许可和维护费用来计算,对业务规则的修改所产生的成本远远大于前两者。这就是为什么目前大企业使用的集中系统,单修改一个数据接口,就叫价几十万甚至几百万的费用。

判断你的项目或团队是不是适合DDD&&DDD计分卡

根据下方的图片,逐项打分。最后得分为7分或者以上,那么,你应该考虑DDD了。
(做比较麻烦,直接拍照贴图了)
DDD计分卡
DDD计分卡

浅谈一下贫血症和失忆症

什么是贫血领域对象?

概念:贫血领域对象(Anemic Domain Object)这个术语被首次提出时,它并不是一个博得赞美的词汇,他描述的是一个缺少内在行为的领域对象。
但是人们对于贫血领域对象的态度褒贬不一。问题在于,多数开发者认为这样的领域对象是正常的,其实不然。他们没有意识到这是一个严重的问题。

领域对象病历自查:
1、你的领域对象中是不是主要是些公有的getter 和 setter 访问器,并且几乎业务逻辑,或者完全没有业务逻辑。
2、软件组件经常使用的领域对象是否包含了系统主要业务逻辑,并且多数情况下你需要调用那些setter 和 getter?你可能会将这样的客户代码称为服务层或者应用层代码。

提示:正确答案是:要么两项均为YES,要么均为NO。
答案都是NO,表明你的领域对象是健康的。
答案都是YES,表明你的领域对象已经病的不轻了,这就是贫血对象。

其实大部分开发者所说的领域对象,并不是真正的领域对象。而是将关系型数据库中的表模型映射到了对象上而已。这样做的代价太大并且收益小。

可能你看到这里会感觉,我们开发都是先设计关系型数据结构,然后直接将数据表映射成实体对象,而且没有感觉他是不健康的。如果你有这种想法,这并不是DDD。你要知道DDD软件设计并不是从关系型数据开始的。

举例说明贫血对象对你的代码做了什么?

下面这段代码应该是你经常写的,并且在你看来是完美的。

public void SaveCustomer(Customer model)
{
	...
	Customer customer=customerDao.GetCustomer(model.CustomerId);
	if(customer==null)
	{
		customer=new Customer();
	}
	customer.UserName=model.UserName;
	customer.Sex=model.Sex;
	customer.Telephone=model.Telephone;
	....
	customerDao.Save(customer);
}

上边这个例子,我想在你的项目中出现的频次是最高的。
我想说的是,我们看到了一个欠妥的设计,我们可以将其重构成更好的模型。
在DDD中,我们不关注是如何保存Customer数据的,而是如何更好的向模型中添加业务价值。
Customer对象并不是一个领域对象,而是一个数据持有器。

上边的代码功能很强大。不管是一个Customer是新建的还是已经存在的;不管Customer的UserName变了,还是Sex变了,还是Telephone更改了。这段代码都可是实现保存。

实际在DDD中,我们并不能通过SaveCustomer看到业务场景。
如果你是新加入的开发者,当你看到SaveCustomer时,你并不知道项目代码中有多少地方调用了SaveCustomer方法,你也不知道这些调用的地方为什么调用他。你需要去比对项目历史代码,并话费大量时间去阅读代码。哇!!!原来,这tmd才是惊喜(SaveCustomer)啊。

我们将这种情况成为:由贫血症导致的失忆症。

该如何DDD呢?通用语言和限界上下文

通用语言和限界上下文同时构成了DDD的两大支柱,并且他们相辅相成。

通用语言

概念:通用语言是团队共享语言,是团队自己创造的公共语言,是领域专家和开发者使用相同的通用语言进行交流。结合业务语言、工业标准语言、和开发者技术语言。
(我感觉不单单是领域专家和开发者,团队中的每一个人都应该使用通用语言。)

关于通用语言没有太多要说的内容,大家在实际工作中,也偶有遇到。我更想说的是如何在团队中建立通用语言机制。

  1. 同时绘制物理模型图和概念模型图,并标注名字和行为。
  2. 创建一个包含简单定义的术语表。并标注这些术语是好或者不好,备注出好与不好的理由。
  3. 找到团队中的其他人员来检查。

好了就写到这里吧。有些概念后期我会逐步更新,什么是领域,子域,如何判定限界上下文。我也在学习中。。。。。。。。。。

已标记关键词 清除标记
©️2020 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页