0

不太确定如何解决有关 DDD 的这个问题。

假设您有 2 个域:

  • Product负责创建新的和管理Products一个人创建的现有的域。Product Aggregate Root
  • 一个Store域,负责将所有创建的内容分配给要出售Products的给定对象,以及其他内容。Store但是他们Store也可以创建新Products的,将分配给自己,但也可供其他人使用,Stores以便他们可以分配Product给自己。Store Aggregate Root

AProduct可以存在而不属于 a Store。AStore可以在没有任何内容的情况下存在Products(我知道这没有任何意义,但这只是我正在处理 atm 的复杂解决方案的一个简单示例。)

因此,当 aPerson出现在系统中时,它们可以从任一端开始。他们可以从创建新的Products开始,也可以从添加新的Store.

这就是复杂的地方,当他们创建一个新的 时Store,他们可以选择添加现有的Products,或者他们可以创建一个新的Product并将其添加到Store.

你如何处理这个用例。是否Store有一个行为来CreateNewProduct负责设置新的Product然后将其添加到Store. 还是您只是在域Product之外创建一个新Store域作为域的一部分Product,然后告诉Storeto AddProduct/ AddExistingProduct

更新:这样的事情是否适合作为Domain Service

public class StoreProductService {

    public Store CreateNewStoreProduct (Store store, string sku, string name, etc){

        Product newProduct = ProductFactory.CreateNewProduct(sku, name, etc);

        store.AddProduct(newProduct);

        return store;
    }
}
4

2 回答 2

1

您需要两个域相互通信。您可以使用各种方法进行通信,但一种常见的方法是使用 REST API。在您的 Store 域中,您需要能够与 API 通信或知道如何与 API 通信的东西。我通常将这些实现为包装 api 调用的服务。该服务将能够理解您的域通用语言并将其翻译成 API 命令。您可以使用域事件来监听产品何时创建,然后您可以将商店与产品相关联,或者您可以实现某种轮询机制。

请求了一个示例,所以这里是:

从 UI 调用(可能来自控制器)

StoreService.CreateStore(storeName: String, newProduct : StoreProduct) 您可以传入原语来表示新产品。这使您可以创建新产品而无需为其创建新类。您随后不需要在域和 UI 层之间共享基础设施类或转换器。

商店服务

public StoreService
{
      public StoreService(ProductApiClient productApiClient...)...
      public void CreateStore(string StoreName, StoreProduct prod...)
      {
             var newStore = StoreFactory.Create(storeName);
             //below might be better as an asynch call but for simplicity
             //keeping it all synchronous
             var newProd = productApiClient.CreateProduct(prod);
             //check if product was created successfully, if so
             newStore.Add(newProd);
             //save
             StoreRepo.Create(newStore);
             //check if store was created successfully
       }

从这里可以看出的要点:

  1. 使用工厂创建您的聚合实体(在此状态下它没有被持久化)。
  2. 您需要一个存储库来序列化新存储并将其持久化到数据存储中。
  3. productApiClient 将在您的域模型和对 productApi 的请求之间进行转换。它知道如何在给定域实体的情况下生成 Api 请求(例如,如果是 REST)。
  4. ProductApiClient 将从 Api 响应中返回一个域实体。
  5. 您使用商店实体将新产品添加到商店。
  6. 您使用 repo 持久化您的商店
  7. 如果对 api 的调用很耗时,您可以选择更异步的方法。

这个例子说明了 DDD 的力量和关注点的分离。根据您的项目规模和您的要求,这可能会过于乏味,因此请根据您的需求、技能和要求进行调整。

于 2016-03-08T15:59:47.663 回答
1

这个业务问题很常见。您肯定可以找到一些有关使用 DDD 的电子商务系统的示例。

典型的情况是你还没有完成你的 UL 开发。如果您与您的领域专家讨论商店(我不会将其标记为代码,因为我谈论的是 UL 术语,而不是类),您会发现商店只关心产品可用性,而不是产品本身。

通常,属于产品目录的产品与可用性无关。它可能有一般描述、制造商详细信息、原产国、图片、包装尺寸和重量等。

然而,产品可用性具有可用性,即可用产品项目的数量。它可能有一些额外的细节,例如保留物品的数量、预计到达的物品等等。

事实是,尽管这两个概念有很大不同,但它们通常被领域专家称为“产品”。这是两个独立限界上下文的典型示例。

一旦您在两个不同的限界上下文(和物理位置)中有两个称为 Product 的不同事物,您就需要使它们保持同步。这通常是通过在有界上下文之外发布域事件并通过在那里订阅这些事件并在有界上下文中执行内部域命令处理来更新另一方来完成的。

于 2016-03-08T14:55:16.997 回答