丰富的域名模型。抗贫血领域模型

时间:2013-12-17 19:10:13

标签: c# dependency-injection domain-driven-design domain-model anemic-domain-model

许多讨论,例如thisthis,都与 RICH DOMAIN MODEL

一起使用

并且有2 strong reason about amenic,例如1和3:

  

现在让我们说我需要确保我需要验证它   产品存在于库存中,如果不存在则抛出异常。

所以有一个问题:如果我们不需要一个对象依赖于ISomeRepository之类的服务,我们可以这样做:

public void Order.AddOrderLine(IEnumerable<Product> products, Product product)
{
    if(!prosucts.Contains(product))
         throw new AddProductException

    OrderLines.Add(new OrderLine(product));
}

并将其称为:

Order.AddOrderLine(ISomeRepository.GetAll(), product);

2 个答案:

答案 0 :(得分:1)

听起来你的域名中缺少一个概念。我考虑引入某种StoreInventory实体,以便产品从库存中移出并进入订单(在许多商业领域中称为“挑选”)。

interface StoreInventory
{
    IEnumerable<Product> AvailableProducts { get; }
    Product PickProduct(guid productId); // This doesn't have to be an Id, it could be some other key or a specification.
}

void Order.AddOrderLine(StoreInventory inventory, Product product)
{
    if (!inventory.AvailableProducts.Contains(product.Id))
        throw new AddProductException();

    var item = inventory.Pick(product);
    OrderLines.Add(new OrderLine(item);
}

这对我来说似乎更贴近现实。但与DDD一样,只有您的域专家可以告诉您应该如何流动。

这在未来似乎也更具可扩展性,例如使用此模型可以很容易地引入多个商店 - 每个商店都有自己的库存。

答案 1 :(得分:0)

如果您阅读有关DDD的信息,您会发现Repository是DDD的核心概念。在DDD中,存储库是域的一部分,并说明域需要什么样的行为才能使持久性工作。在您的情况下,您可以简单地将存储库传递给方法并让方法提取必要的数据。

public void Order.AddOrderLine(ISomeRepository repo, Product product)
{
    if(!repo.ProductExists(product))
         throw new AddProductException

    OrderLines.Add(new OrderLine(product));
}

// call it like
Order.AddOrderLine(someRepository, product);

我认为你混淆的问题是存储库,或者更准确地说,它是抽象的,通常与持久性本身有关。这实际上是误解整个模式造成的误解。正确的存储库由两部分组成:抽象,通常由接口表示,它定义了域对持久性的要求。以及使用持久性技术实现这些操作的具体实现。