建立领域驱动设计统一过程

简介: 建立领域驱动设计统一过程

本文尝试指出领域驱动设计的四个不足。目前我们采用的领域驱动设计,其主线是Eric Evans提出的所谓领域驱动设计元模型。该元模型因其高度的概括性与松散性,故而能够随着时间推移历久不衰。但也正因为此,使得它在指导领域驱动设计落地时,缺乏规范性和实践意义,更多需要凭借经验才能成功实施领域驱动设计。


领域驱动设计肇始于Eric Evans出版于2004年的著作《Domain-Driven Design-Tackling Complexity in the Heart of Software》: 


image.png


领域驱动设计作为一个软件系统综合分析和设计的面向对象建模过程,如今已经发展为一种针对大型复杂系统的领域建模过程体系。


它改变了传统软件开发工程师针对数据库建模的方法,而是面向领域,将要解决的业务概念和业务规则转换为软件系统中的类型以及类型的属性与行为,通过合理运用面向对象的封装、继承、多态等设计要素,降低或隐藏整个系统的业务复杂性,并使得系统具有更好的扩展性,应对纷繁多变的现实业务问题。


领域驱动设计元模型


领域驱动设计的立意是建立以领域为驱动力的过程体系,在这一核心驱动力的设计思想指导下,并没有死板僵化的构建过程来约束你。Eric Evans定义了一套领域驱动设计元模型,该模型由诸多松散的模式构成:

image.png


至今,这套元模型在领域驱动设计的实施中仍然发挥着重要作用。


显然,领域驱动设计是开放的。从领域驱动设计诞生至今,整个社区并未放弃发展其体系的努力,也诞生了许多重要的补充模式,例如以“领域事件(Domain Event)”为核心的诸多模式:事件溯源(Event Sourcing)、CQRS模式等。


随着微服务和中台战略的兴起,领域驱动设计元模型中的限界上下文(Bounded Context)、核心领域(Core Domain)又得到了空前绝后的重视。


然而,在团队运用和实践领域驱动设计过程中,整套体系始终存在力有未逮之处。毕竟,领域驱动设计是否能够取得成功,不只限于一两位精通领域驱动设计的专家就可以力挽狂澜。团队成员的能力、管理规范等诸多因素都会影响整个实践的过程。


据我个人的经验和对实施领域驱动设计的反思,认为现行的领域驱动设计存在以下四个不足。


不足之一


Eric Evans构建的领域驱动设计元模型并不足以支撑软件的构建过程。这些模式之间虽然彼此影响,运用得当就能形成设计合力;然而模式的粒度并不均衡,运用上极为随意,缺乏一个统一的过程指导。


虽然领域驱动设计划分了战略设计阶段与战术设计阶段,但这两个阶段的划分仅仅是对构成元模型的模式进行类别上的划分,例如将限界上下文、上下文映射等模式划分到战略设计阶段,将聚合、实体、值对象等模式划分到战术设计阶段。


缺乏一个统一的过程去规范这两个阶段需要执行的活动、交付的工件以及阶段里程碑。Eric Evans没有清晰定义这两个阶段该如何衔接,它们之间执行的工作流到底是怎样的。


除了极少数精英团队,大多数团队都需要一个清晰的软件构建过程,否则将茫然不知所措。领域驱动设计没能形成这样的统一过程,就使得其缺乏可操作性,团队在运用领域驱动设计时,更多取决于设计者的行业知识与设计经验,使得领域驱动设计在项目上的成功存在较大的偶然性。


因此,领域驱动设计缺乏一个规范的过程指导,是其不足之一。


不足之二


领域驱动设计倡导以“领域”为核心驱动力,无论是对领域知识的抽象还是精炼,本质上都是针对问题域的业务需求。


可是,业务需求是如何获得的呢?获得的业务需求应该具备什么样的特征?业务需求的粒度和层次是怎么定义的?该如何规范和约定团队各个角色对需求分析的参与?以及在不同的阶段,业务需求的表现形式与验证标准分别是什么?


种种问题,领域驱动设计都没有给出答案,甚至根本就未提及!虽然说这些问题都可以纳入到需求管理体系,故而可以认为它们游离于领域驱动设计之外;可是,不同层次的业务需求贯穿于领域驱动设计过程中的每个环节,识别限界上下文需要对业务需求和业务流程有着清晰的理解,建立领域模型需要的领域知识和概念也都来自于用户故事层次的业务需求。毫无疑问,需求管理体系会直接影响领域驱动设计的质量。


因此,领域驱动设计没有匹配的需求管理体系,是其不足之二。


不足之三


领域驱动设计战略阶段的核心模式是限界上下文,指导架构设计的主要模式是分层架构,前者决定了业务架构,后者决定了系统架构。


领域驱动设计的核心诉求是让业务架构和系统架构形成绑定关系,以面对需求变化时,使得系统架构能够适应业务架构的调整,满足架构的演进性。领域驱动设计虽然给出了这些模式的特征,却失之与简单松散,不足以支撑复杂软件项目的架构需求。


因此,领域驱动设计缺乏面向领域的架构体系,是其不足之三。


不足之四


领域驱动设计以模型驱动设计为主线,却没有给出明确的领域建模方法。


无论是否采用敏捷的迭代建模过程,建模分为分析、设计与实现这三个不同的活动确是客观存在的事实。虽然我们必须努力保证领域模型的一致性,但这三个活动存在明显的存续关系,每个活动的目标、参与角色与建模知识存在本质差异,这也是客观存在的事实。


基于此,我们需要分别为领域分析建模、领域设计建模和领域实现建模提供对应的方法指导,减轻每个建模活动的知识负担,明确每个建模活动获得的领域模型的验证标准,避免领域建模的随意性。


因此,领域驱动设计没有领域建模固化流程的支撑,是其不足之四。


精简和丰富知识体系


针对领域驱动设计的四个不足,我对领域驱动设计的知识体系进行了精简与丰富。


精简,意味着做减法,就是要剔除领域驱动设计元模型中不太重要的模式,凸显核心模式的重要性,并对领域驱动设计过程进行固化,提供更为直接有效的实践方法,建立具有目的性和操作性的构建过程。


丰富,意味着做加法,就是突破领域驱动设计的范畴,扩大领域驱动设计的外延,引入更多与之相关的知识体系来丰富它,弥补自身的不足。


要构建全新的领域驱动设计体系,还需要匹配软件构建的目标。软件构建就是不断对问题域求解,获得解决方案进而组成完整解决方案域的过程。若要构建优良的软件系统,那么在这个构建过程中,还需要控制软件的复杂度。因此,我们需要在问题域与解决方案域的背景下定义能够控制软件复杂度的领域驱动设计过程,并将体系的内容限定在领域关注点的边界之内,避免体系的扩大化。


既然要支持软件构建过程,就需要结合项目的管理过程。


项目的管理过程姿态万千,如何与领域驱动设计结合,却属于空白区域。


例如,当团队采用Scrum过程时,产品待办项(Product Backlog)与冲刺待办项(Sprint Backlog)与领域驱动设计要建模的领域知识有什么关系?当开发人员领取一个用户故事进行开发时,是否意味着在此时才开始领域建模?什么时候开始识别整个系统的限界上下文,又到什么时候结束这一业务架构的分析工作?


如果采用RUP来指导软件的构建,那么该如何区分业务建模与领域驱动设计之间的关系?在领域驱动设计中,用例起到了什么样的作用?在设计基于组件的系统架构时,这些可重用的组件是否就等同于限界上下文呢?


领域驱动设计统一过程


鉴于此,我们构建的领域驱动设计体系就必须形成一个统一过程。


宏观层次,以需求管理体系和面向领域的架构体系为支撑;微观层次,通过领域建模固化流程来保障解决方案的落地;同时糅合领域驱动设计元模型中有价值的模式作为参考,甚至形成能够重复执行的最佳实践。


如此,就可以使得这一体系做到规范与松散互补充,固化与开放相结合。我将这一体系称之为“领域驱动设计统一过程(Domain-Driven Design Unified Process,简称为DDD-UP)”:

image.png


领域驱动设计统一过程参考了RUP的结构,整个过程用两个坐标轴来表达:

  • 横轴代表了推动领域驱动设计在构建过程中的时间,体现了过程的动态结构,构成元素包括阶段(Phase)、迭代(Iteration)。其中阶段又分为三个阶段,分别为:全局分析阶段、架构规划阶段和领域建模阶段。
  • 纵轴表现了领域驱动设计在各个阶段中执行的工作,体现了过程的静态结构,构成元素包括角色(Workers)、工作流(Workflow)和元模型模式(Pattern)或方法(Method)。


采用这一结构的目的就是希望为领域驱动设计引入一个规范而统一的过程,让团队在实施领域驱动设计可以变得有章可依,有章可循,而不仅仅是靠一两个人的经验来决定成功的高度。


搭建整个领域驱动设计统一过程是一个庞大的体系,我会在后续文章中对该过程做概要的描述。我个人正在编写的书籍《解构领域驱动设计(暂定名)》,也将按照这个过程体系进行编写。

相关文章
|
数据采集 人工智能 机器人
RPA+BPM:企业流程自动化的最佳拍档
RPA可以和BPM实现优势互补。BPM通过对业务管理规则和逻辑的科学梳理并显性化体现,给RPA提供了大脑和神经网络。RPA的所有行为依赖清晰可被定义的逻辑规则。BPM给了RPA所依赖的逻辑规则,就像BPM为RPA提供了大脑和神经网络。
3786 0
|
C# Windows
C#通过代码实现快捷键编辑
C#通过代码实现快捷键编辑
266 1
|
存储 缓存 NoSQL
【分布式】Redis与Memcache的对比分析
【1月更文挑战第25天】【分布式】Redis与Memcache的对比分析
JeecgBoot架构图 ● 技术架构图 ● 系统架构图
JeecgBoot架构图 ● 技术架构图 ● 系统架构图
|
SQL 存储 NoSQL
SQL、NoSQL还是NewSQL
【7月更文挑战第5天】SQL、NoSQL还是NewSQL
391 1
|
搜索推荐 Linux
深入理解Linux操作系统的启动过程
本文旨在揭示Linux操作系统从开机到完全启动的神秘面纱,通过逐步解析BIOS、引导加载程序、内核初始化等关键步骤,帮助读者建立对Linux启动流程的清晰认识。我们将探讨如何自定义和优化这一过程,以实现更高效、更稳定的系统运行。
可靠性
(1)系统能够在规定条件和时间内完成规定功能的特性,是所有网络信息系统的运行和建设的基本目标。 (2)通过抗毁性,生存性与有效性进行衡量。 (3)可靠性是在给定的时间间隔和给定条件下,系统能正确执行其功能的概率。 (4)提高可靠性需要强调减少系统中断(故障)的次数。
|
算法 Linux 调度
深入理解操作系统中的进程调度
【9月更文挑战第28天】在操作系统的复杂世界中,进程调度是维持系统高效运作的关键。本文将深入浅出地探讨进程调度的核心概念及其对系统性能的影响。从进程调度的定义和目标出发,逐步解析不同类型的调度算法,并通过实际代码示例,揭示这些算法如何在真实系统中实施。无论你是初学者还是有经验的开发者,这篇文章都将为你提供宝贵的见解和知识。
|
前端开发 开发者 UED
CSS进阶-CSS Sprites技术
【6月更文挑战第14天】**CSS Sprites是一种合并多个小图至大图的技术,减少HTTP请求,提升页面加载速度。本文探讨了精灵图的核心概念,常见问题(如定位不准、适应性问题、维护困难)及解决方案。建议使用工具精确计算坐标,采用媒体查询适应不同屏幕,建立图标管理机制,并提供代码示例展示如何应用。尽管有WebP、SVG等新技术,但在处理大量小图标时,CSS Sprites仍是高效选择。理解和掌握此技术对前端开发者至关重要。**
279 2
|
SQL 存储 测试技术
SQL Server 查询超时问题排查
【8月更文挑战第14天】遇到SQL Server查询超时,先检查查询复杂度与索引使用;审视服务器CPU、内存及磁盘I/O负载;审查SQL Server配置与超时设置;检测锁和阻塞状况;最后审查应用代码与网络环境。每步定位问题根源,针对性优化以提升查询效率。务必先行备份并在测试环境验证改动。
1060 0