有界的上下文实现和设计

Dav*_*New 12 domain-driven-design aggregateroot repository-pattern onion-architecture bounded-contexts

假设我有两个有界的上下文,即Shipping ContextBilling Context.这些背景中的每一个都需要了解客户.

在数据级别,客户由CustomerTbl数据库中的表表示.该表包含描述客户的所有必要列.

CustomerTbl(简化)中的列:

  • Name
  • PhysicalAddress
  • PaymentMethod

装运情境关注的是NamePhysicalAddress计费上下文关注的是NamePaymentMethod.

装运背景中,我已对聚合建模Recipient:

  • Recipient现在有属性/值对的对象NamePhysicalAddress

结算上下文中,我已对聚合建模Payer:

  • Payer具有属性/值对的对象NamePaymentMethod

两者RecipientPayer聚合都完全由上下文边界分隔.他们也有自己的存储库.

问题:

  1. 是否可以使用相同的"数据库表"来拥有多个聚合(假设它们位于不同的有界上下文中)?

  2. 在更多有限的背景下可能需要客户数据.这不意味着每个有界上下文的许多聚合,存储库和工厂实现吗?代码中会有一定程度的冗余.这不会影响可维护性吗?

  3. 跨聚合共享属性是否可以接受?一个例子是客户Name财产.这也意味着冗余的验证码?

Lod*_*rds 9

Q&A

1)使用相同的"数据库表",是否可以使用多个聚合(假设它们位于不同的有界上下文中)?

  • 只要您遵循管理共享状态的严格策略,我就可以接受.
  • DDD是可以接受的,因为域被认为比数据更重要.
  • 只要在不引入(太多)隐藏成本的情况下完成工作,您的客户就可以接受.

2)在更多有限的背景下可能需要客户数据.这不意味着每个有界上下文的许多聚合,存储库和工厂实现吗?代码中会有一定程度的冗余.这不会影响可维护性吗?

不一定,看一下共享内核模式.

3)在聚合中拥有共享属性是否可以接受?一个例子是客户名称属性.这也意味着冗余的验证码?

与问题1相同的答案.关于冗余,一旦拥有共享内核,您可以简单地将验证器类放在那里.

关于DRY和DDD之间的冲突:

优雅的代码并没有不必要地使伟大的设计原则相互矛盾.通常有一种方法可以满足这些原则.你还没有找到它,因为要么你不理解这些原则,要么你没有足够地解剖你的问题.

(如果这听起来很教条,那是因为软件工程实际上是一种宗教)