DDD,全称 Domain Driven Design,即领域驱动设计。在大型复杂业务系统的架构实践中,它常常扮演着关键角色,对于提升系统的扩展性和可维护性大有裨益。
听起来是不是既高级又有点抽象?具体该如何落地?有没有一些可以遵循的经验法则?或者,对于一名新手,怎样才能快速上手呢?
理解核心概念
领域
领域本质上就是一个特定的问题域。例如,社区的核心问题是会员、发帖、回帖;电商的核心则围绕会员、店铺、商品、库存、交易、营销展开。一旦确定了业务领域,系统要解决的关键问题及其边界也就基本框定了。当然,你在一个领域深耕越久,积累的技术与业务经验也会越丰富。
设计
这里的设计主要指领域模型的设计。领域模型是整个系统的灵魂,每个业务领域都对应一个领域模型,它能有效地帮助我们应对复杂的业务挑战。
驱动
“驱动”意味着以领域为边界,先分析其中的核心问题与关注点,然后据此设计领域模型,最后让模型来驱动代码的实现。因此,开发一个系统时,我们应尽量先厘清领域模型,再动手编码,这样的系统在后期会更容易维护。
划重点
- 核心思想是通过设计领域模型来解决领域中的关键问题,这是一种模型驱动的思维方式,而非走一步看一步的面向过程编程。
- 设计领域模型时,必须确保其满足业务规则(在DDD中常称为“不变性”),同时要综合考虑技术实现,例如并发问题。领域模型不是纯粹的概念模型,它关心技术实现,因此能直接指导编码。
- 要抓住核心问题,而不是试图解决领域内的所有细枝末节。
- 设计应具备一定的抽象性、通用性和复用价值。
- 模型需要持续重构、完善与优化,它是一个不断演进的过程。
领域模型的设计思路
1. 理解业务领域
首先要明确:我们要构建一个什么样的系统?它要解决什么核心问题?接着,将大问题拆解、将需求细化。在细化过程中,很可能会发现许多模糊不清的地方,这时就需要与需求方(可能是产品经理或业务代表)进行深入沟通。有时需求方自己也未必完全清晰,此时,一位领域专家(对领域内的各种业务场景、规则了如指掌的人)就显得至关重要。
2. 拆分业务领域
如果一个领域的业务规则、交互流程和涉及的数据过于庞大,导致我们难以直接对其进行建模,那么就需要进行拆分。将一个大的领域拆分为多个较小的子域,并理清每个子域的边界。接着,需要识别哪些是核心子域,哪些是非核心子域,哪些是公共支撑子域,并思考子域之间的关联。
划分子域的标准通常是按业务功能进行。例如:
- 会员域:注册、登录、用户信息管理、权限标签。
- 商品域:商品信息录入、商品详情页、商品管理。
- 交易域:订单生成、订单管理。
3. 细化每个子域
针对每个子域,进一步明确其核心关注点:
- 梳理出领域内我们关注的概念及其相互关系,统一交流术语,形成统一语言。
- 梳理出领域内关键的业务规则(不变性),例如唯一性约束、账户余额不能为负等。
- 梳理出领域内的核心业务场景,例如电商中的“加入购物车”、“提交订单”、“支付”。
- 梳理出领域内的关键业务流程。例如,下单会经历哪些具体步骤?先别急着考虑流程引擎或设计模式,用伪代码把过程列出来,再思考如何对不同场景的流程进行合并、抽象和优化。
4. 进行领域模型设计
DDD提供了一系列实用的建模工具:聚合、实体、值对象、工厂、仓储、领域服务、领域事件。我们可以运用这些工具来设计每个子域的领域模型,最终产出领域模型图。下图展示了一个电商系统商品中心的领域模型示例:

5. 考量技术要素
在模型指导下的技术选型与设计同样重要,这包括:框架选型、系统架构设计、容量规划、数据库设计、分库分表方案、缓存策略、高并发解决方案以及监控报警体系等。
架构层面的考量

- 服务治理
- 熔断、限流、隔离、降级:这些都是构建高可用分布式系统不可或缺的保障措施,用以防止雪崩效应,确保核心服务的稳定性。
领域驱动设计不仅仅是一套设计模式或方法论,更是一种强调以业务为核心、通过模型驱动开发的思维方式。从理解领域、拆分子域,到设计模型、落地架构,每一步都要求开发人员紧密贴近业务。希望本文的梳理能帮助你更清晰地把握DDD的脉络,为你的系统设计与架构工作带来启发。
|