Yujun's Blog

DDD(四):领域与子域

June 3, 2025 (4d ago)DDD

DDD(四):领域与子域

在刚学习DDD的时候,我们会接触到一套特别多的名词:什么领域、子域、核心域、通用域、支撑域、限界上下文、聚合根、实体、值对象…… 。

但是一切的出发点,都是DDD的核心思想:分而治之和聚焦概念。这些概念都是为这两个目标服务的。当我们能从这个角度去看待它们时,一切都会变得清晰起来。

想象一个大型“在线电商平台”(这是我们的领域)。

它可以被拆分为: 商品中心(管理商品信息、分类、库存) - 子域 订单中心(处理下单、支付、履约) - 子域 用户中心(管理用户注册、登录、账户信息) - 子域 营销中心(负责优惠券、促销活动) - 子域 物流中心(对接物流公司、跟踪配送) - 子域

无论什么场景,我们都在做同样的事情:分解复杂度。这是人类解决复杂问题的本能。

现在,我们聚焦于领域(Domain)、子域(Subdomain)、核心域(Core Domain)、通用域(Generic Domain)和支撑域(Supporting Domain)。这些是战略设计层面的基石。

领域与子域

百度百科对领域的解释:领域具体指一种特定的 范围 或区域。从构建系统的角度,领域,可以理解为,企业要解决的整体业务问题空间

假设现在我们要为一个大型零售集团构建IT系统。其“领域”就是整个零售业务,包含了从商品采购、库存管理、线上线下销售、会员营销、供应链协同、财务结算到售后服务的全部范畴。这是一个很大且及其复杂的系统性问题。

面对如此庞大的领域,任何单一团队或系统都难以有效应对。因此,我们要对其进行战略性的分解。形成若干个职责相对内聚、耦合相对松散的“子问题域”,这就是子域

比如,上例中,子域可能包括商品子域:负责商品信息的统一管理、分类、SKU定义、价格策略等;库存子域:管理各仓库、各渠道的实时库存;订单子域:处理来自各渠道的订单创建、支付、履约、状态跟踪、逆向流程(退换货)等;会员子域:管理会员信息、等级、积分、权益、营销活动参与等;供应链子域:与供应商进行采购订单、物流、对账等信息的交互。

理解领域和子域之间的关系很简单,其实就是分而治之的思想。但是如何在领域内划分子域却是一个很棘手的问题,比如:有些领域边界特别模糊,不好划分。例如:某些子领域两边都靠,不知道怎么取舍的问题?

如何划分?

“分而治之”谁都懂,但如何分才是精髓和难点所在。糟糕的子域划分,不仅不能降低复杂性,反而可能制造新的麻烦和更高的维护成本。

那么子域划分有哪些原则呢?笔者这里也暂时没有总结出好的原则。

但是我们可以先有一个起点,一方面可以借鉴已有的、传统意义上的模块划分经验。在很多成熟的业务系统中,已经存在一些按照功能合的模块,例如“用户管理模块”、“产品管理模块”、“订单管理模块”。这些模块在业务上体现了一定程度的内聚性,可以作为初步识别子域的起点。

需要注意的是,这里强调的是“某类业务的功能聚合”。要避免将纯粹的技术组件(如“日志模块”、“缓存模块”)误认为业务子域。子域必须承载业务含义。

另一方面很多领域的边界就是流程的边界 ,比如商品、订单、货物,他们分别属于不同的流程,很自然的就形成了业务领域的边界。

也就是作为新手,我们可以有一个非常重要的划分边界---​业务流程的边界​。一个相对完整的、端到端的业务流程,其不同的阶段或环节,往往可以自然地形成子域的边界。

但是,同时也要注意业务流程中的关键状态变化点,或者处理责任发生转移的地方,往往是潜在的子域边界。 例如,订单从“待支付”到“已支付”,从“待发货”到“已发货”,这些状态的改变往往往往意味着背后有一堆不同的事情要做(不同的业务逻辑和规则)。处理这些不同事情的,可能是系统里不同的“部门”或“专家”(不同的业务单元或系统)。 因此就常常可以作为我们划分不同业务功能区域(也就是子域或限界上下文)的线索

最后,作为技术人员,在划分业务子域时,更多是扮演引导者、提问者和模型提炼者的角色,还要通过与最懂业务的领域专家(通常是资深的业务人员、产品经理等)协作,将他们的隐性知识显性化为清晰的子域边界和模型。避免技术人员凭空臆断业务边界。

核心域 、通用域和支撑域

现在我们有了一堆的子域。但并不是所有子域对我们业务的成功都具有同等的重要性。 这时候,核心域、通用域和支撑域的概念就派上用场了。它们帮助我们识别不同子域的战略价值,从而决定资源投入的一个优先级。

核心域必须由企业内部最顶尖的技术和业务专家主导,投入最优质的资源进行自主研发和持续创新。绝不能轻易外包或采用通用解决方案。同时也是业务变化最频繁、创新需求最旺盛的地方,系统设计必须具备高度的灵活性和可扩展性,以支撑业务的快速迭代。

通用域是指指那些非企业独有、业界有成熟解决方案、多个子域或多个企业都会用到的通用功能。它们是必要的,但不是差异化竞争的关键。如用户登录、权限管理。几乎所有系统都需要。

支撑域这类子域对业务运营是必需的,但它们本身不直接贡献核心竞争力,也不像通用域那样有广泛的标准化解决方案。它们往往需要一定的定制化以满足特定业务需求,通常是为了支撑核心域的运作。如电商平台的商品上下架审核、订单异常处理后台。这些功能虽然重要,但用户不会因为你的后台做得好就选择你。

总结

  • 领域与子域的划分是DDD战略设计的起点,其核心目标是通过“分而治之”的策略,将庞大复杂的业务问题分解为一系列更小、更易于理解和管理的问题单元。这是后续进行限界上下文划分和微服务设计的基础。
  • 核心域、通用域、支撑域的识别,则是在子域划分的基础上,从企业战略和商业价值的角度,对不同子域进行重要性排序和资源投入策略的制定。

作为CRUD Boy,在理解这些概念时,千万不能仅仅停留在定义层面。不然和别人一交流就会露馅。尝试将它们应用到自己所熟悉的一个业务场景中去(比如参与过的项目,或者一个常用的APP),思考:

  • 这个系统的整体领域是什么?
  • 它可以被划分为哪些子域?划分的依据是什么?
  • 在这些子域中,哪些是你认为的核心域?为什么?哪些是通用域?哪些是支撑域?
  • 如果让我们来主导这个系统的重构或新版本的规划,会如何根据这个分类来分配资源和制定技术策略?

通过这样的不断的思考练习,这些抽象的概念才能真正“活”起来,并转化为架构设计能力的一部分。DDD不是银弹:这里可以思考下DDD解决不了什么问题,但它提供了一套强有力的思维工具,帮助我们更好地理解业务,从而构建出更符合业务本质的软件系统。

Comments