DDD 101 — 5分钟导览
AWS 安全上线!
我喜欢疯狂的挑战。
在巴黎的一次会议上,组织者邀请我填补一个闪电演讲的空缺(演讲开始前一小时),我不仅接受了,还决定介绍一下领域驱动设计 (DDD)。没错,就是领域驱动设计 (DDD)——这门诞生于一本560页厚的书里的学科。
不幸的是,即使我成功地吸引了一屋子(PHP!)开发人员的注意来谈论我所关心的话题,我也不知道演示是否足够强调DDD的两个关键方面。
我写这篇文章的目的是为了再试一次,并有更多的时间准备。
DD什么?
在你因为缩略词恐惧症而离开这篇文章之前,你可能想知道,DDD 充满了各种闪亮的新设计模式。设计模式……有趣的是,它们正是我最初被吸引到这个世界的原因……而最有趣的是,它们却是这个世界中最不重要的元素。
那么,什么是 DDD?
当我使用键盘时,听着键盘敲击的声音,我喜欢理解我正在写的代码(容易),理解前一天写的代码(不那么容易),理解六个月前写的代码(有挑战性),而最让我感到满足的是看到其他开发人员理解我写的代码。
即使是傻瓜也能写出计算机能理解的代码。优秀的程序员能写出人类能理解的代码。
— 重构:改进现有代码的设计,1999 年
关于这个问题,我最美好的回忆发生在几年前。当时,我请团队里的一位开发人员为应用程序添加一个功能。我没有告诉她太多关于代码组织方式的细节,她回来时有点困惑,并要求确认:“我只需要在这里或那里添加几行代码……就完成了,对吗?”
她说得太对了。我设计的这个对象模型一眼就达到了预期的效果,真是太神奇了——而且是第一次读就成功了。
对我来说,这就是领域驱动设计的全部意义——表达一个有意义的面向对象模型,说明它的作用。
DDD 提醒您常识规则,并提供了一套想法、原则和模式来实现它。
DDD 与标准 OOP 有何不同?
问得好——没什么。
DDD 只不过是将 OOP 应用于业务模型而已。(当你深入研究 DDD 时,你会证明我错了,但现在我们就先接受这个答案吧。)
我将用我的个人经验来尝试解释为什么我认为 DDD就是简单的 OOP。
当我第一次了解 DDD 时,我已经是一个热情的 OOP 实践者,并且我曾经多次倡导 OOP(发表演讲、进行结对评审等等)。
尽管当时我被认为是一个令人满意的开发人员,但我内心深处知道我的代码有问题,有些问题我无法弄清楚,有些问题与我无法编写涵盖业务规则的有意义的单元测试有关。我知道我的代码所讲述的故事并不像我希望的那样富有表现力。
但由于似乎没有人抱怨,我继续学习模式、模式、再模式。
在我购买“蓝皮书”(领域驱动设计:解决软件核心的复杂性)之前,我浏览了其中的内容,看到了工厂、存储库、值对象、实体以及这种极具吸引力的模式,可以吸引任何极客的注意。
正是他们说服了我投入时间(和金钱)来读这本书。尽管我渴望了解新的花式图案,但我还是忍不住读完了书的导言。
无处不在的语言
我记不清这句臭名昭著的引文里的每个字,也记不清每条规则,但我记得我从一开始就被迷住了。无处不在的语言的概念是一场革命。
尽管名称复杂,但其含义却直截了当——实话实说。其基本规则是:“要知道什么是‘铁锹’;如何使用它;它有什么作用……去问懂行的人。”
哦天哪!你就因为这个就喜欢上这本书了吗?
嗯,这听起来可能很明显,但这正是阻碍我编写自解释代码的主要问题。别嘲笑我,我的经验告诉我,我并不孤单(而且并非每个人都被治愈了)。
我们这些开发者中,有多少人只是看了一眼需求就直接开始写代码了?有多少程序员只是粗略地浏览了一下业务规则,就直接开始项目的框架和数据库部分了?别装了——我肯定知道!
我不能怪我们。这些要求读起来通常很乏味,至少和写出来一样乏味(这叫做因果报应)。
好消息是,事情不必如此。
只有你理解了,你才能解释
为了能够解决一个问题,我必须了解它(以及它的复杂之处)。
如果你不能向六岁的孩子解释清楚,那你自己就不明白了。
— 阿尔伯特·爱因斯坦
其推论是:“为了了解一个问题,我必须采访处理这个问题的人。”
敏捷方法认证
“与正确的人交谈。”这听起来很熟悉。
个体和互动高于流程和工具
可工作的软件高于详尽的文档
客户协作高于合同谈判
响应变化高于遵循计划— 敏捷宣言
当然,如果你选择编程是因为你更愿意与电脑而非人类交流,那么这可能是一个难以接受的残酷现实。但是,如果你正在寻找一个完美的社交场合,摆脱IT狂人的刻板印象,那么好消息是,你的机会来了。
不再有枯燥的项目
“与商人交谈;他们会乐于解释他们的工作和问题,你也会喜欢倾听并找到解决方案。”
它确实改变了我对 IT 的看法。
作为一名年轻的开发者,我曾对解决技术难题的想法感到兴奋,但现实项目中缺乏挑战性却常常让我感到失望。不,计算保险计划的价格并不是什么挑战……在特定日期找到最便宜的酒店房间也并非如此……你只会花时间写出你在几秒钟内就弄清楚的东西。
但是,当你与那些需要你的技能来寻找解决方案、节省时间或提高产品质量的业务人员交谈时,一切都会变得有趣,因为你会产生一种使命感。你不仅要为解决方案编写代码,还要成为解决方案本身的一部分,了解它的“为什么”、“是什么”、“何时”……而挑战在于如何以一种能够揭示这一使命的方式编写代码。
i 不及格!(j 和 x 也不及格。)
“给变量命名时,应该像给第一个孩子命名一样小心。”
― Robert C. Martin,《代码整洁之道:敏捷软件工艺手册》
上述引言与“无处不在的语言”这一概念更加契合。每个类、每个方法、每个变量都应精心命名,确保它们讲述的故事与你正在编写的业务故事相符。并牢记领域驱动设计 (DDD) 的理念:“这些名称应该与业务部门达成一致。” 为什么?因为将来,当你们讨论新功能或提交错误报告时,彼此都能理解。代码反映了业务现实。
如果有人需要被说服有意义的变量名是强制性的,只要问他们就可以了。
您更愿意阅读以下哪本书?
<?php | |
if ($data[$i][$j] > $x) { | |
//some code here | |
} |
<?php | |
if ($data[$i][$j] > $x) { | |
//some code here | |
} |
或者
<?php | |
if ($activityReport[$employeeId][$month] > $salesGoal) { | |
//some code here | |
} |
<?php | |
if ($activityReport[$employeeId][$month] > $salesGoal) { | |
//some code here | |
} |
直到今天,没有人忽略这一点......除了一个人,“不,我永远不会用 PHP 编写或阅读任何东西。”
健康检查——贫血还是正常?
言归正传,我们之前说过,DDD 就是将 OOP 应用于业务模型。读完这本书后,我自然而然地问了自己一个很简单的问题。
“我的对象模型是真正的对象模型吗?还是这只是伪装的程序代码?”
我意识到我过去总是把所有的精力都集中在数据上,而没有适当地专注于随之而来的过程,所以我患上了贫血模型综合症。
这种反模式的根本恐怖之处在于,它与面向对象设计的基本理念——将数据组合起来并一起处理——截然相反。贫血领域模型只是一种过程式设计[…]。更糟糕的是,许多人认为贫血对象是真实的对象,从而完全误解了面向对象设计的真正意义。
— 马丁·福勒 — 马丁·福勒的 Bliki
为了自我诊断代码的混乱程度,我问自己:“我能用哈希表替换所有对象吗?之后我的代码还能正常工作吗?”答案是肯定的。
我已经养成了将数据和智能分开的习惯——这与面向对象编程的信条相悖——这也解释了为什么我经常最终会有数百个服务来操纵愚蠢的数据对象……而肥胖的控制器则试图协调由此产生的混乱。
DDD 的经验法则 — — 将数据和智能结合在一起……
……并设定界限,让他们分开
此时,我终于理解了两个主要概念——我正在与商务人士交谈,以便代码能够反映他们的问题,并且我正在使用真实对象来建模解决方案。
然而,随着项目的发展,我仍然需要克服两个障碍:冲突和复杂性。
当我们尝试为不同语境中使用的类似概念寻找名称时,就会出现冲突,而随着模型开始包含更多智能,就会出现复杂性。
我想到的最容易解释的例子是Client。
物流团队客户、营销团队客户、会计团队客户……
问题在于,“客户”是业务团队实际使用的名称,但这个名称本身就隐含着依赖于上下文的规则和约束。我们的第一反应是想与实际名称有所不同,但规则是必须坚持使用业务术语。
然后,我们回忆一下DDD的另一个重点—— 有界上下文。
有界上下文是将单一职责原则应用于你的领域模型。系统的每个部分都有其自身的智能、数据和词汇。每个部分彼此独立。
现在是讨论模式的时候了吗?
哦,图案……我几乎忘记了。
是的,DDD 带来了很多模式。做好准备吧;你很快就能轻松学会它们了。
您可以使用实体(ID 很重要)和值对象(值很重要)来建模您的业务。您可以使用存储库 (Repositories)来检索和存储它们。您可以使用工厂 (Factory)来创建它们。如果某个对象过于复杂,无法用单个类来处理,您可以创建聚合 (Aggregates) ,将实体和值对象绑定到同一个根目录下。如果业务逻辑不属于给定对象,您可以定义服务 (Service ) 来操作相关元素。最终,当业务状态发生变化(业务专家关注的变化)时,您将发布领域事件 (Domain Events)来传达该变化。
好了,我们已经讨论了 DDD 模式!
但最终……*这*是 DDD
其余的都不重要。
进一步阅读
- 正如其名称所暗示的,《领域驱动设计速成》是一本简单但全面的 DDD 入门读物。
- 当然,埃里克·埃文斯 (Eric Evans) 所著的《领域驱动设计:解决软件核心的复杂性》一书是这一切的开端。
鏂囩珷鏉ユ簮锛�https://dev.to/geraldcroes/ddd-101--the-5-month-tour-1e9