领域驱动设计DDD入门系列

发表于2019-10-15,长度3626, 41个单词, 10分钟读完
Flag Counter

领域驱动设计不是新概念,但却是刚火起来的概念。这里通过7节课带你入门DDD。本系列课程整理自Oreilly的视频课。这是第一堂课:为何DDD?

这堂课介绍的是DDD相关的概念,以及为何你应该认真考虑在自己的项目里使用DDD。我们会通俗地讲解DDD的战略和战术建模工具,希望你能“无痛”地学会使用DDD(因为很多人都觉得学习DDD很痛苦)。这里会对比好的、坏的、高效的设计,并告诉你高效设计是优先考虑的。之后介绍DDD的战略战术工具。最后讨论如何使用DDD去提炼你的业务模型。

为什么要学习DDD?并且要快点学会?首先想到的当然是改善我们的产品 – 好的开发人员都热衷于持续完善自己的东西。俗话说“活到老学到老”,当出现了能切实改善产品设计的技术时我们都会情不自禁地选择进修。现在这种技术来临了:DDD就是最可能改善我们产品质量的思考方式。另一个原因是DDD为我们带来了很多工具,能够提升我们项目的成功率,帮助我们发挥优势,战胜对手。DDD就是建模工具,它能帮你根据你公司独特的商业需求设计应用。此外,DDD能让应用容易扩展,并达到最佳性能。

有人认为DDD是十分复杂的软件开发范式。真的是吗?从性价比上讲不一定,DDD的确提供了很多高级开发工具,要掌握它们的确不太容易。所以本系列就是帮你提升DDD能力的,让你从此“无痛”建模。


那么我们说一下好的设计和不好的设计。你喜欢哪种设计?毫无疑问,我们都会选择好的设计。这里我们会讲一些好的设计原则和一些没那么好的原则,你一定能够学会一些技术。

有些团队使用任务看板,也就是移动一些便签,从一列到另一列:一般是敏捷项目。由于看板的限制,你没法突破固定模式思维。站立会结束后,你会跑回工位说今天要完成哪些任务,但是却没人教你更好完成任务。现在有些人称之为“免设计”,简直是扯:没有免设计,只有好设计和坏设计。实际上,当你离开看板回到工位开始编写代码时,设计就出现了,每个人写代码时总会有自己的想法。当然了,这些想法最终免不了演绎成不好的设计。敏捷开发一条重要的原则是知识获取,这很对。不过不仅仅是把便签从TODO移到in progress再移到done,这不是敏捷的初衷。敏捷既然是知识获取,那在开发前就要先获取知识,这才叫设计!通过知识获取,每个人都或多或少了解到业务领域的某些方面,这样就有机会开发出更有竞争力的产品。但今天的产业界依然遍布坏设计,从咨询公司到教育行业,我们会花费大把时间用于纠正这些坏设计,提升软件开发能力。所以留意你自己的业务领域。

有时候,软件开发被认为是成本中心而非利润中心(就是说是花钱的而非赚钱的)。这是个潜在的大问题,会让开发人员士气低落。这种公司通常不了解无纸化的好处,他们很少用电脑,觉得开发是累赘。而有的公司很其中开发人员,他们的产品质量很高,开发斗志昂扬。在这种公司,开发有更好的名声还有更高的收入。不过开发也不能太过于看重技术,觉得技术是商业银弹。通常好的设计比好的技术更重要。

如果你喜欢某个框架、或产品、或类似的,觉得它们能让你开发出好的软件,很可能最终会失望。你肯定愿意通过好的设计来实现软件。其中之一被视为银弹的是数据库,太多注意力被放在数据库和数据模型上而非业务过程和操作上。数据是很重要的,非常重要;没有数据我们将无处安放自己的开发能力。但是,业务流程才是理解组织内部什么更重要、更独特真正的关键。好的设计可以引导你正确高效地理解业务、处理数据、利用数据。所以要留意将太多精力放在数据库和数据模型设计上的潜在问题。

很多(太多)开发人员没有给业务流程、业务对象命名划出足够的重视和强调。我们听过很多类似的声音:“就是个名字”“就是个物品”“就是个软件”“和名字无关”!这实际是倒退的态度。坦白讲,命名很重要!它连接了业务思想和软件设计。否则就得建立一套从业务对象到软件实体的映射关系。通过软件的实现就能正确理解业务逻辑是优秀的设计,所以正确(良好)的名称很重要。所以也要留意这个潜在的问题。

实践中还有很多隐藏的问题。比如产品和开发之间协调不畅,产品文档写的让开发理解不了等。我们实在想要将业务操作和软件设计有机整合,这样两个团队就能有机协作,文档也没那么重要了。我们反对基于文档驱动的工作方式,每个人在自己的办公室或小格子里割裂的工作。这也是个难以发现的问题,实际上团队协作是相当重要的方式。

产品工时预估常被赋予很大关注,因为预估不准就会引起延期等问题。这个我就更反对了!让开发人员对即将实现的软件给出估时,是将开发从他们的“主营业务”中剥离,是让他们脱离实际开发。他们越在意开发时间点越会开发出烂产品,因为这会花费他们太多时间和精力去研判。我们想要开发人员能从类似的小事中脱离出来。这门课会提供给你正确可信的工时估计方法。

再说一下前面说的任务看板。敏捷和“免设计”模式会导致开发出“大泥球”!啥是大泥球?下堂课我们再讨论,你先记住这是个潜在问题。我看到有开发人员把业务逻辑写进了用户接口和持久层代码中,这会导致数据库锁竞争引起性能下降。进一步,错误的模型抽象将导致错误的解决方案,达不到需求期望。有的开发尝试高度抽象的解决方案,这可能导致他们最终远离最初的需求,在错误的路上渐行渐远。这在咱们业界还挺流行!这门课也会教你如何避免错误的抽象。

系统间的强耦合会让系统难以维护,这大家都知道,但我看到在微服务架构中广泛存在。这门课也会教你如何解决微服务中的强耦合问题。由于强耦合,微服务会导致失败的业务逻辑和不可调和的混乱数据,课程也会讲解如何避免。要知道一点:软件建模是有意或无意形成的,这对应了好设计和坏设计。无设计一定是个谬论,不存在的。它愚弄了很多人想跳过设计阶段进行快速开发高质量软件,实际形成的是脱离业务和难以维护的产品。所以实际上有一条沟在业务需求和软件实现之间,我们想协调它们,一定不会不经过设计。

我们关注的好设计 – 你可能知道比好设计“更好”的是高效设计。好设计使用的是好技术,而高效设计引导我们盯住业务需求真正期望的点上,让我们理解什么是我们公司真正突出的。 说到突出,你要明白,我们的业务一定是在某一方面突出的。我们一般做不到各方面都突出,比如保险公司会尽力让自己在保险业中最强,但一般不会是好的数据库公司、会计公司。知道我们公司的业务优势,能帮助我们开发出更具针对性的产品,更好的符合业务需求。这就是高效设计,它帮助开发人员根据独特的业务需求建模出正确的软件模型。

你有在老路上走过吗?就是那种可能上百年的路。路面遍布坑洞,还有高低起伏,看起来不舒服,似乎名不符实。谁设计了这条路?那么多年都发生了什么?一开始它可能是给马车走的土路,走的车也不多。这就是它的设计目标。建好之后发生了什么?越来越多的人、车开始使用这条路。路可能也被拓宽过一些。最终,有人给它铺上路面,但它的使用依然距离最初的设计不远。变成今天的道路(不管今天多么不舒服)的那条旧马车路与高速公路之间有什么区别?差别就是告诉公路是特意设计的,经过大量调研、设计工程勘察,最终实现为高速路。高速路上行车方便多了,拐弯也不用踩刹车了;而老路怎么改造也比不上高速路一开始的样子。老路太难用了,还危险。软件开发的角度是一样的。可能是一开始像马车路一样简陋后来经过升级,也可能是一开始就设计良好、考虑深远、调研充分像高速路一样。后者方面、安全。高效设计就会实现这样的效果,软件思考和修路思考是一样的。


DDD 工具用得好会让你事半功倍,它们会帮你进行高效设计。其中我认为最有效的DDD工具箱是战略设计工具。从中你可以掌握有界上下文、通用语言、内容映射、子域等。这些工具会特别有效地帮你提升设计能力。对不少开发人员,战略设计时全新的思维方式。你可能就是这样,所以不要忽略它。

此外DDD还提供了战术建模工具,这门课会介绍其中最重要的两种:聚合和领域事件。聚合帮你控制事务、维护业务和数据一致性。领域事件可以通过对事实、领域模型中的重要事件进行建模来帮助你。这两个工具用好了,可以构造出更稳定、更满足技术需求的贴近通用语言的软件。但不要过多强调战术工具,因为战略工具更重要,重要得多。因为战术工具可能受限于开发平台、技术选型、开发语言(函数式语言或面向对象语言)。不过我选的这两种战术工具是所有战术工具中应用最广泛的,所以平台、语言和技术平台都能用。

我们会发现的是DDD是关于知识琢磨,知识获取的。在使用DDD时你将要琢磨的知识量是至关重要的。它可能像一个漏斗,倾倒的是大量想法、主意、试验、文档,漏出来的是一滴特别特别重要的知识,是对输入理解后的高度浓缩。这个完全是实验性质的,这门课会教你如何加速获取知识以满足我们面临的苛刻时间表。这样你可以带领团队达到软件设计新高度,就可以进行高效设计了。


尽管这门课程很短,覆盖不了DDD的全部知识,但我相信通过学习你能掌握DDD中最重要的部分。Good luck!

Written on October 15, 2019
分类: dev, 标签: ddd
如果你喜欢,请赞赏! davelet