title: 架构师学习-DDD author: Gamehu date: 2025-07-11 21:54:50 tags:
构建一个在线电子商务系统(E-Shop)的设计示例。这个示例将从宏观的战略设计(如何划分系统边界)到微观的战术设计(代码层面的核心元素),全面展示 DDD 的核心思想。
DDD 的首要原则是软件必须植根于领域,并且模型需要有清晰的边界。
场景: 假设我们要构建一个大型在线商店,不仅涉及用户下单,还需要处理库存发货和销售报表。
传统问题: 许多团队会试图创建一个包含所有属性(如用户、订单、商品、库存、报表)的单一庞大模型。这会导致模型臃肿,不同职能的团队互相干扰。
DDD 解决方案: 我们将系统划分为两个独立的界定的上下文(Bounded Contexts),:
核心思想:
在“在线交易上下文”内部,我们使用战术模式来构建领域模型。
开发人员与业务专家(如销售经理)共同制定一套语言。
为了隔离关注点,我们将系统分为四层,:
Order、Customer 等业务对象和规则。这是软件的心脏。这是领域模型的基本构建块。
实体(Entity):
Order(订单)。Order 是一个实体,必须有唯一的标识符(Identity),。值对象(Value Object):
Address(送货地址)。Address 应该是不可变的(Immutable),如果客户搬家了,我们是用一个新的 Address 对象替换旧的,而不是修改旧对象,。为了保证数据一致性,我们需要划定修改数据的边界。
Order(订单)可能包含多个 OrderItem(订单项)。Order 是这个聚合的根(Aggregate Root)。Order),不能直接引用内部的 OrderItem。如果想修改某个订单项的数量,必须通过根的方法(如 order.updateItemQuantity())来进行。这确保了订单总价等不变量(Invariants)在修改过程中始终保持一致,。有些动作不属于特定的对象。
CheckoutService(结账服务)或 FundTransferService(转账服务)。Order 或 Customer 都不合适,因此我们创建一个无状态的领域服务来封装这些操作,。为了解耦领域模型与数据库。
OrderRepository。findOrder(id),不关心底层是 SQL Server 还是 Oracle。资源库负责从数据库中检索数据并将其重建为领域对象(如 Order 聚合)。这让开发人员可以像从内存集合中获取对象一样获取领域对象,而无需在业务逻辑中编写 SQL,。结合上述概念,一个“用户修改收货地址”的业务场景在代码设计中如下流转:
CustomerRepository)。Customer 聚合(实体)。Customer 实体的业务方法(如 customer.moveTo(newAddress))。Customer 实体将旧的 Address 值对象替换为新的 Address 值对象。Customer 聚合保存回数据库。这个设计示例体现了 DDD 的核心:通过将软件实现与业务领域模型紧密绑定,来应对复杂性。
为了巩固理解,我们可以用书中提到的汽车制造来类比这个系统设计:
https://github.com/Sairyss/domain-driven-hexagon?tab=readme-ov-file