DDD客户,联系人和地址(聚合根)

Chr*_*eis 4 domain-driven-design aggregateroot

我正在构建一个管理我公司大部分LOB内容的应用程序.我正试图围绕DDD ......从客户管理开始.关于域模型,很多例子非常非常简单,这对我没有多大帮助.

我的聚合根是一个Customer类,它包含一组地址(地址簿),一组联系人和一组通信历史记录.

看起来像这样的聚合根将是巨大的,具有修改地址,联系人(可以有x个电话号码)和通信的功能.

例如

UpdateCustomerName(...)
SetCustomerType(...) // Business or individual
SetProspect(...) // if the customer is a prospect
SetDefaultPaymentTerms(...) // line of credit, etc. for future orders
SetPreferredShippingMethod(...) // for future orders
SetTaxInfo(...) // tax exempt, etc.
SetCreditLimit(...)
AddAddress(...)
RemoveAddress(...)
UpdateAddress(...)
VerifyAddress(...)
SetDefaultBillingAddress(...)
SetDefaultShippingAddress(...)
AddContact(...)
UpdateContact(...)
RemoveContact(...)
SetPrimaryContact(...)
AddContactPhoneNumber(...)
RemoveContactPhoneNumber(...)
UpdateContactPhoneNumber(...)
AddCommunication(...)
RemoveCommunication(...)
UpdateCommunication(...)
etc.
Run Code Online (Sandbox Code Playgroud)

我已经读过,值对象没有标识.在该系统中,每个地址(在数据库中)具有ID,并且具有customerId作为外键.如果Address是它自己的聚合根,那么我将无法使用我的业务逻辑来设置默认账单/发货.许多示例都有没有ID的值对象...我不知道如何在没有它的情况下将更改保留到Customer表中.

Anywho,感觉就像我的结构走错了道路,如果它会变得如此巨大.有人做过类似的事吗?不确定如何分解结构并维护基本业务规则(例如确保在将客户设置为默认结算或发货之前将地址分配给客户).

Lar*_*rry 7

您正在考虑业务逻辑应该存在的问题的原因是因为您正在混合有限的上下文.LoB应用程序是DDD中的典型示例之一,其中大多数示例将应用程序分解为多个有界上下文:

  • 客户服务
  • 开票
  • 运输
  • 等等.

每个有界的上下文可能需要您的Customer类中的一些信息,但很可能不是全部.在接近实体的定义时,DDD违反标准的DRY概念.可以定义多个Customer类,一个用于需要它的每个有界上下文.在每个有界上下文中,您将定义具有属性和业务逻辑的类,以满足该有界上下文中的要求:

  • 客户服务:联系信息,联系历史记录
  • 结算:结算地址,付款信息,订单
  • 运送:订单项,送货地址

这些有界的上下文都可以指向同一个数据库或多个数据库,具体取决于系统的复杂程度.如果它是同一个数据库,您可以设置数据访问层以填充有界上下文所需的属性.

史蒂夫史密斯和朱莉勒曼在Pluralsight上有一个非常棒的课程,叫做领域驱动设计基础,深入介绍这些概念.

  • 很棒的解释.谢谢. (2认同)