软件系统的复杂性
- 隐晦:
- 抽象层面的隐晦,抽象系统时,每个人都有自己特定的视角,你需要站在对方的角度才能明白他为什么这么做
- 实现层面的隐晦,代码是一种技术实现,通常与现实世界的业务概念脱节,无形中增加了理解成本
- 耦合:
- 代码层面的耦合扩大了修改范围
- 模块层面的耦合需要跨模块/服务交互
- 系统层面的耦合则需要跨团队协作
- 从代码到模块再到系统,耦合的影响逐渐扩大,成本随之增加
- 变化:
- 业务需求决定了系统功能,不同的用户需求不一样,不同的业务发展阶段需求在不断变化
- 系统功能要随着业务需求的变化不断调整,这时就涉及到系统改动的频次和范围

DDD(Domain-Driven Design,领域驱动设计)是应对软件设计复杂性的方法之一,它能很好的解决上述三个问题

什么是领域,什么是领域驱动设计
领域驱动设计(Domain-Driven Design,简称DDD)是一种软件开发的架构理念,它强调在开发过程中优先考虑业务需求和领域知识,将业务逻辑与实现细节分离,并构建出能够准确反映业务概念的软件模型。通过这种设计方法,开发者可以更好地理解业务需求,从而设计出更灵活、更易于维护的系统。
什么是领域?
领域是指一个特定的知识或问题的范围,它包括了用户、他们的问题以及解决问题的方案。 具体来说,领域由以下三个部分组成:
-
涉众域(Stakeholder Domain):这是领域的用户群体,包括所有对领域有利益相关的人,如客户、最终用户、业务分析师、项目经理等。这些用户有着不同的角色和需求,他们的需求和期望是设计系统时需要重点考虑的因素。
-
问题域(Problem Domain):这是用户所面临的问题或挑战,也就是他们需要解决的业务痛点或实现的业务价值。例如,在一个电商领域中,用户可能需要解决如何高效管理库存、如何提高订单处理速度等问题。
-
解决方案域(Solution Domain):这是针对问题域中问题的解决方案。它包括了实现这些解决方案的技术选择、设计模式、架构决策等。在DDD中,解决方案域特别强调将领域知识和业务逻辑紧密地与软件设计相结合。
什么是领域驱动设计?
领域驱动设计是一种软件开发方法,它专注于理解和建模复杂的领域知识,并将这些知识直接映射到软件设计中。 它提倡开发人员与领域专家紧密合作,共同理解领域,从而设计出更加准确和有效的软件系统。
具体来说,DDD包含以下几个核心概念:
- 领域模型(Domain Model):这是一个抽象的模型,用来表示领域中的概念、它们之间的关系以及它们的行为。领域模型是领域知识的容器,它帮助开发人员和领域专家沟通和理解业务逻辑。
- 实体(Entities):具有唯一标识的对象,它们的生命周期跨越多个操作,其身份是核心属性。
- 值对象(Value Objects):没有唯一标识的对象,它们的属性是不可变的,且行为主要由其值定义。
- 聚合(Aggregates):一组相关联的实体和值对象,它们作为一个整体被修改,以确保内部一致性和完整性。
- 领域服务(Domain Services):执行领域逻辑,但不属于任何特定实体或值对象的操作。
- 仓储(Repositories):负责抽象数据访问,使得领域模型不需要关注数据持久化细节。
- 领域事件(Domain Events):表示领域中发生的事件,可以被用来触发其他操作或通知系统中的其他部分。
营销领域的示例
以营销系统为例,该系统服务于四类用户:运营、销售、电销人员和商户。
系统的核心问题是:
- 如何发券:通过何种方式或活动来发放优惠券。
- 发给谁:确定优惠券的目标人群。
- 发什么:决定发放何种类型的优惠,如红包、折扣券等。
针对这些问题,解决方案包括:
- 营销活动:通过不同的活动类型来承载发券行为,每种活动类型对应不同的玩法,如买赠、折扣、充送等。
- 目标人群:定义和选择特定的用户群体来接收优惠券。
- 权益定义:明确优惠券的具体内容,如红包、代金券、折扣券等。
在DDD的视角下,这些概念可以被建模为领域模型中的实体、值对象和服务。例如:
- 营销活动可以是一个实体,具有唯一的标识和生命周期。
- 目标人群可以是值对象,定义了活动的受众特征。
- 权益也是值对象,定义了优惠的具体内容。
通过这样的建模,系统能够更好地反映业务的复杂性,并且易于扩展和维护。同时,领域专家和开发人员之间的沟通也会更加顺畅,因为模型直接映射了他们的共同理解。
领域驱动设计的三步骤
- 战略设计:确定用例,统一语言和划分边界。
- 战术设计:概念模型转化成类(代码)模型。
- 代码架构:将系统设计映射为系统实现。
