本书是Eric Evans对他自己写的《领域驱动设计-软件核心复杂性应对之道》的一本字典式的参考书,可用于快速查找《领域驱动设计》中的诸多概念及其简明解释。
Ⅰ.让模型起作用
领域驱动设计是一种开发复杂软件的方法:
1.专注核心领域。
2.探索领域从业者和软件从业者的创造性协作模式。
3.在一个明确的限界上下文内讲通用语言。
DDD的三点总结依赖于本手册定义的术语来定义。
很多项目做建模工作最终没有获得太多的实际好处。DDD模式从项目中提炼成功的实践使得建模带来了巨大的好处。总的来说,他们提出了一个与先从细节再到高层次的视角【1,在DDD之前我们大部分都习惯于先进行数据表的设计】完全不同的建模和软件开发的方式。严格的建模惯例必须平衡好与非技术人员【2,一般这里指领域专家】合作进行的模型探索。战术和战略必须结合才能成功,DDD同时涉及战术和战略的设计。
限界上下文
任何大型项目都有多个模型。它们出现的原因很多。两个子系统通常服务于非常不同的用户群体,具有不同的工作,其中建立不同的模型可能是有作用的。团队独立工作由于缺乏沟通可能以不同的方式解决了同样的问题。工具集也可能不同,这意味着程序代码不能共享。
多个模型是不可避免的,而当基于不同模型的代码被合并时,软件变得充满BUG,不可靠,而且难以理解。团队成员之间的交流变得困惑。在什么情况下不应该使用模型通常是不清楚的。
模型表达式与其他任何短语一样,仅在上下文中具有含义。
因此:
明确定义模型适用的上下文。根据团队组织,应用程序特定部分的使用情况以及例如代码库和数据库模式等物理表现明确设置边界。应用“持续集成”可使模型概念和术语在这些范围内保持严格一致,但不要被外部问题分散或混淆。在上下文中标准化一个单独的开发过程,这个开发过程不需要在其他地方使用。
通用语言
首先写下一个句子,
然后将它分成小段,
再将它们打乱并重新排序。
仿佛是巧合一样,
短语的顺序对意思完全没有影响。
–Lewis Carroll, “Poeta Fit, Non Nascitur”
要想创建一种灵活的、蕴含丰富知识的设计,需要一种通用的、共享的团队语言,这种语言应该是时刻进行检验的,遗憾的是,在软件项目上很少出现这样的检验。
在一个单一的限界上下文内,语言可能会以某种方式被破坏,削弱了在应用复杂建模上的努力。如果该模型仅用于为团队的技术人员绘制UML图,那么这对DDD核心的创造性合作没有任何贡献。
领域专家使用他们的术语,而技术团队成员有自己的语言来从设计的角度讨论这个领域。日常讨论的术语与代码中嵌入的术语(最终是软件项目最重要的产品)。甚至同一个人在说和写中都会使用不同的语言,使得这个领域中最尖锐的表达常常以暂时的形式出现,而这种形式永远不会在代码中甚至在书面中被捕捉到。
翻译会导致沟通不畅,使得知识匮乏。
然而,这些语言都不能成为一种共同的语言,因为没有一种服务于所有需求。
领域专家应该反对别扭或不足以传达领域理解的术语或结构;开发人员应该注意有无歧义或不一致将妨碍设计。
在谈论这个系统的时候,带上模型。使用模型的元素和交互来大声描述场景,以模型允许的方式结合概念。找到更简单的方法来说出你需要说的话,然后把这些新的想法带回图表和代码中。随着语言的普及,模型不仅仅是一个设计品。它成了开发人员和领域专家一起要完成的不可或缺的事情。
因此:
使用模型作为语言的支柱。保证团队在团队和代码中的所有交流中不懈地运用这种语言。在一个限界上下文中,在图表,写作,尤其是交流中使用相同的语言。
意识到言语的改变就是对模型的改变。
通过实验替代表达式来体现替代模型来解决困难。然后重构代码,重命名类,方法和模块以符合新模型。解决对话中的术语混淆,就像我们对普通单词的意义认知是一致的一样。
持续集成
一旦定义了限界上下文,我们就必须保持它的健康。
当许多人在一个相同的限界上下文里工作时,模型碎片化会是一个强烈的趋势。团队越大,问题就越大,但只有三四个人就会遇到严重的问题。然而,将系统分解成更小的上下文最终会失去一个整合和内聚的价值。
因此:
经常研究一个合并所有代码和其它实现工件的过程,通过自动化测试来快速标记碎片。不懈的运用通用语言,随着概念在不同人的头脑中的演变,逐渐形成对模型的共同观点。
模型驱动设计
将代码与底层模型紧密联系在一起给出了代码的含义,并使模型具有相关性。
如果设计或其中心部分没有映射到领域模型,那么该模型没有什么价值,并且软件的正确性是可疑的。同时,模型和设计功能之间的复杂映射是难以理解的,并且实际上不可能保持的像设计的改变一样。在分析和设计之间设立一道红线,使得在每一个这样的活动中获得的洞察力都不会影响到另一个。
从模型中提取在设计中使用的术语和职责的基本分配。代码成为模型的表达式,所以对代码的改变就是对模型的改变。从而它的影响必然涉及到该项目的其余活动。
因此:
设计软件系统的一部分,以非常直观的方式反映领域模型,以便映射是显而易见的。重新审视模型并修改它,以便在软件中更自然地实现,即使您试图使其更深入地反映领域。需要一个单一的模型,来除了支持一个顺畅的通用语言之外,同时满足目的正确。
动手建模者
如果编写代码的人不对模型负责,或者不知道如何使模型适用于应用程序,那么模型与软件无关。如果开发人员没有意识到改变代码会改变模型,那么他们的重构就会削弱模型而不是加强模型。与此同时,当建模者与实现过程分离时,从未获得或很快失去对实现约束的感觉。模型驱动设计的基本约束是模型支持有效的实现并且抽象出对领域的关键洞察,已经过去了一半,所产生的模型将是不切实际的。最后,如果分工阻止了这种协作,经验丰富的设计师的知识和技能不会转移到其他开发人员,这是传达了模型驱动设计编码的微妙之处。
因此:
任何对模型有贡献的技术人员都必须花费一些时间来接触代码,无论他在项目中扮演什么主要角色。任何负责更改代码的人都必须学会通过代码来表达模型。每个开发者都必须参与一些关于模型的讨论,并与领域专家联系。那些以不同方式作出贡献的人,必须有意的聘请那些在一个通过通用语言动态交换模型想法中接触代码的人。
重构深入的洞察力
使用一套经过验证的基本构建模块以及一致的语言为开发工作带来了一些清晰的思路。这避免了真正找到一个尖锐模型的挑战,一个捕获领域专家的微妙担忧和可以推动一个切实的设计。一个在肤浅的表面下的模型抓住的本质是一个深层的模型。这应该使软件更符合领域专家的思维方式,并且更加符合用户的需求。
传统意义上,重构是被用于描述由技术动机进行代码转换的词。重构也可以通过对领域的洞察以及对代码中模型或其表达的相应改进来激发。
复杂的领域模型很少发挥作用,除非通过重构的迭代过程来开发,包括领域专家与有兴趣了解该领域的开发者的密切参与。
原创文章,转载请注明本文链接: https://zacharyfan.com/archives/287.html
关于作者:张帆(Zachary,个人微信号:Zachary-ZF)。坚持用心打磨每一篇高质量原创。欢迎扫描二维码~
定期发表原创内容:架构设计丨分布式系统丨产品丨运营丨一些思考。
如果你是初级程序员,想提升但不知道如何下手。又或者做程序员多年,陷入了一些瓶颈想拓宽一下视野。欢迎关注我的公众号「跨界架构师」,回复「技术」,送你一份我长期收集和整理的思维导图。
如果你是运营,面对不断变化的市场束手无策。又或者想了解主流的运营策略,以丰富自己的“仓库”。欢迎关注我的公众号「跨界架构师」,回复「运营」,送你一份我长期收集和整理的思维导图。