【问题标题】:DDD Customer, Contacts, and Addresses (aggregate root)DDD 客户、联系人和地址(聚合根)
【发布时间】:2016-07-06 18:33:57
【问题描述】:

我正在构建一个应用程序来管理我公司的大部分 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.

我读到值对象没有身份。在这个系统中,每个地址(在数据库中)都有一个 ID,并且有一个 customerId 作为外键。如果地址是它自己的聚合根,那么我将无法使用我的业务逻辑来设置默认计费/运输。许多示例都有没有 ID 的值对象...我不知道如何在没有 ID 的情况下将更改保存到我的 Customer 表。

任何人,如果我的结构变得如此巨大,我感觉我的结构走错了路。有人做类似的事情吗?不知道如何分解结构并维护基本业务规则(例如在将地址设置为默认计费或送货之前确保将地址分配给客户)。

【问题讨论】:

    标签: domain-driven-design aggregateroot


    【解决方案1】:

    您之所以反对业务逻辑应该位于何处的问题,是因为您混合了有界上下文。 LoB 应用程序是 DDD 中的典型示例之一,其中大多数显示应用程序被分解为多个有界上下文:

    • 客户服务
    • 计费
    • 运费

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

    • 客户服务:联系信息、联系记录
    • 账单:账单地址、付款信息、订单
    • 送货:订单项、送货地址

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

    Steve Smith 和 Julie Lerman 开设了一门很棒的 Pluralsight 课程,名为 Domain-Driven Design Fundamentals,深入介绍了这些概念。

    【讨论】:

    • 很好的解释。谢谢。
    • 现在我只需要弄清楚如何在单独的有界上下文中加载的数据模型之间进行同步(我没有使用事件溯源)。例如。计费客户域模型需要一个地址列表,以确保分配的默认计费地址确实存在......但是地址将在客户服务有界上下文中进行管理
    • 更新功能应该在这些更新发生的任何上下文中。关键是您可以为计费上下文创建一个模型,该模型仅具有用于填充默认计费地址的属性。如果计费上下文中没有发生更新,那么您不需要该功能。
    • 至于保持上下文是最新的,这取决于您的数据库设计。您是否有一个由多个上下文查询的数据库?如果是这样,每个上下文将是一致的。在 Pluralsight 课程中,他们讨论了数据库设计的不同选项,但实际上是基于偏好。我看到你有 EF 经验,所以我会用它作为例子。您可以为每个有界上下文定义不同的 EF DbContext。在每个中,您只使您将要查询的表可用。
    • 如果您使用 CodeFirst,您仍需要维护一个 DbContext 用于包含所有 DB 实体的迁移。
    猜你喜欢
    • 1970-01-01
    • 2016-03-21
    • 2016-11-05
    • 1970-01-01
    • 2012-02-19
    • 1970-01-01
    • 2010-12-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多