欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

领域驱动开发-重读随想

程序员文章站 2021-12-12 11:39:12
一、前尘往事作为程序员,一直以来,我们都被不断新增、且不断改变的需求折磨的欲仙欲死。于是,寻找心中的那枚“银弹”的梦想,成了我们孜孜不倦追随各路大神的动力。记得2年前,一个偶然机会被“好的软件就应该是DDD(领域驱动设计)的”所安利,于是将Vaughn Vernon的大作《实现领域驱动设计》请回了家。当然,如大部分人一样,不久这部神作就变成了“枕头”。其中原因,一方面是这套书理论性太强,另一方面(主要)是入门姿势不对,被一堆概念如“界限上下文(Bounded Context)”、“通用语言(Ubiquit...

一、前尘往事

作为程序员,一直以来,我们都被不断新增、且不断改变的需求折磨的欲仙欲死。于是,寻找心中的那枚“银弹”的梦想,成了我们孜孜不倦追随各路大神的动力。记得2年前,一个偶然机会被“好的软件就应该是DDD(领域驱动设计)的”所安利,于是将Vaughn Vernon的大作《实现领域驱动设计》请回了家。当然,如大部分人一样,不久这部神作就变成了“枕头”。其中原因,一方面是这套书理论性太强,另一方面(主要)是入门姿势不对,被一堆概念如“界限上下文(Bounded Context)”、“通用语言(Ubiquitous Language)”、“领域和子领域(Domain/Subdomain)”、“上下文映射(Context Maping)” 等等弄得晕头转向。

最近微信读书推荐了一本《领域驱动设计(DDD)实现之路》,带着如何更好处理“变化需求”的目的,我再次燃起了重读关于领域驱动设计的兴趣。《领域驱动设计(DDD)实现之路》其实是一本“集思录”,将业内高质量的实践文章合在一起。其中的“DDD该如何学”以及“领域驱动设计(DDD)实现之路”两篇文章,终于可以让我以正确的姿势开始窥视一下“领域驱动开发”的大门了。

二、DDD之战略设计

DDD有战略设计和战术设计之分,战略设计能从高处俯视系统,帮助我们精确划分领域以及处理各个领域之间的关系;而战术设计则从技术实现的层面教会我们如何具体实施DDD。

所谓战略,我觉得就是从大的架构上去看待软件设计。软件架构设计的实质是让系统能够更快地响应外界业务的变化,并且使得系统能够持续演进。在遇到变化时不需要从头开始,保证实现成本得到有效控制。这种响应力体现在新需求(变化)的实现速度上,也体现在我们组件的复用上,在实现过程中现有架构和代码变化点的数量也是技术人员能够切身体会到的。面对日新月异的数字化时代,组织的整体关注点都应该集中到变化的原点,即业务上,而架构应该服务于这种组织模式,让这样的模式落地变得自然。

让我们先简单回顾一下几个重要名词的含义:

限界上下文(BoundedContext) —— 语义和语境上的边界。边界内的每个代表软件模型的组件都有着特定的含义并处理特定的事务。限界上下文中的这些组件有特定的上下文语境和语义理据。可以理解为业务问题及其解决方案所涉及到的语义语境。

通用语言(UbiquitousLanguage) —— 团队在限界上下文中发展了一种语言用于表达其边界内的软件模型,这一语言由在该眼界上下文中开发软件模型的每个团队成员所使用。团队成员间交流用的是它,软件模型实现的也是它。

核心域(Core Domain ) —— 解决方案空间在问题空间中讨论,且当限界上下文被当作组织的关键战略举措进行开发时,即被称为核心域。

子域(SubDomain ) —— 子域是整个业务领域的一部分。可以认为子域代表的是一个单一的、有逻辑的领域模型。大多数的业务领域都过于庞大和复杂,难以作为整体来分析,因此我们一般只关心那些必须在单个项目中涉及的子域。子域可以用来逻辑地拆分整个业务领域,这样才能理解存在于大型复杂项目中的问题空间。

上下文映射(Context Mapping)—— 除了核心域(SubDomain)之外,每个DDD项目还关联着多个限界上下文。所有不属于敏捷项目管理上下文(即核心域)的概念都会被迁移到其他某个限界上下文之中。敏捷项目管理核心域必须和其他限界上下文进行集成,这种集成关系在DDD中称为上下文映射。

通过下面这张全局图,我算是将这几个重要的DDD“术语”串在在了一起,从战略层面,也大概明白了为什么DDD非常强调针对业务问题的分析和分解,并通过识别核心问题域来降低分析的复杂度。
领域驱动开发-重读随想

三、DDD之战术设计

战术设计,就是将战略设计进行具体化和细节化,它主要关注的是技术层面的实施,也是对我们程序员来得最实在的地方。领域驱动设计DDD在战术建模上提供了一个元模型体系(如下图)。其中像“实体、值对象(Entity 、Value Object)”、“领域服务(Domain Service)”以及“资源库(Repository)”等都是我们相对熟悉或有耳闻的方法。而关于“聚合(Aggregate)”以及“领域事件(DomαinEvent)”,我觉得非常值得关注,在《领域驱动设计精粹》中,作者就偏重于对这两套战术进行较为详细的介绍。
其实,大部分DDD的书籍,特别是神作《实现领域驱动设计》,对于战术设计方面的介绍篇幅最多且非常详尽。在有了这些概念后再继续研究,就没那么困难了。
领域驱动开发-重读随想

四、关于技术债

回到看“领域驱动开发”的"初心",面对不断出现的新需求,为了快速实现,必然会埋下或深或浅的“坑”,某种程度上来说,我所追求的其实就是能高效“填坑”的方法,即还技术债。在这书中,竟然有一章就是说技术债的。其提出了非常实用的四条原则:
1.核心领域优于其他子域
2.可演进性优于可维护性
3.明确清晰的责任定义优于松散无序的任务分配
4.主动预防优于被动响应
从中不难看出,其实质就是排优先,抓重点,重预防,很符合我们平时实践的需要。

另外,DDD的核心就在于持续的演进,演进就意味着模型和实现的改变。在"DDD的终极大招"一文中提到,DDD的终极大招By Experience某种意义上是在持续探索,并要求大家接受在这个探索过程中的不确定性——你的设计有可能在未来被证明是错误的。这可能是未来架构设计最大的挑战,我们必须能够让架构持续演进。这从一个侧面也说明,DDD并非不变的“银弹”,也不可能是“银弹”,但却是追求“银弹”之路上的最注重业务与实践的方法论。

作者:侯嘉逊

本文地址:https://blog.csdn.net/vipshop_fin_dev/article/details/107452445