以下哪些示例代表了正确使用DDD? (注意:这是一个提问标题,不需要回答)

5
我是一名有用的助手,可以为您翻译文本。

我已经使用DDD工作了几个月,遇到了一些我不确定的事情。

以向Order对象添加Product的简单示例为例。从我们的控制器中,我们将通过UI传递一个int,该int表示数据库中的Product。以下两个示例哪一个是正确的(如果它们都是错误的,请告诉我)?

示例一:

public class OrderController
{ 
    // Injected Repositories
    private readonly IProductRepository _productRepository; 

    // Called by UI
    public void AddProduct(int productId)
    {
        Order order = ...; // Persisted Order
        Product product = _productRepository.GetProduct(productId);
        order.AddProduct(product);
    }
}

控制器会实例化产品并通过以下方法添加产品本身:
void AddProduct(Product product)
{
    productList.Add(product);
}

例子二:
public class OrderController
{ 
    // Injected Repositories
    private readonly IProductRepository _productRepository; 

    // Called by UI
    public void AddProduct(int productId)
    {
        Order order = ...; // Persisted Order
        order.AddProduct(productId, _productRepository);
    }
}

“Order”领域模型已注入产品存储库,并将其传递给它,然后获取产品并添加它。
Product AddProduct(int productId, IProductRepository productRepository)
{
    Product product = productRepository.GetProduct(productId);
    productList.Add(product);

    return product;
}

我目前选择了第一个示例,因为您的领域模型不应在内部调用服务方法,但最近我看到了一些使用第二个示例的示例,它看起来很整洁。在我看来,示例一几乎是贫血的。示例二将所有产品添加逻辑移动到领域模型本身中。

似乎第一个例子会引导人们将设计朝着贪婪的数据加载方向发展,而第二个则是朝着惰性加载的方向。您更喜欢哪个呢? - Jace Rhea
产品添加到内存列表后,您的订单是如何保存的?是否有一些神奇的事情发生了(抱歉,我不知道C#,也许Order对象是由框架管理的代理?) - Sebastien Lorber
2个回答

2

第二个太糟糕了...

在订单中添加产品时,不应将存储库包含在其签名中,因为存储库不是域的一部分。

我倾向于选择第一个。


实际上,Repository接口是领域的一部分。具体的实现是领域基础设施的一部分:http://dddsample.sourceforge.net/architecture.html - djdd87
当你去超市挑选商品并将其加入购物车时,你是否需要指定存储库?是的,存储库可以被认为是基础设施领域的一部分,但不是业务领域。 - Aliostad
不好意思,我现在正忙着实现 IWheel 接口。但是我很喜欢你的例子 : )。我确实觉得它看起来有点奇怪;虽然它可以让代码更整洁,但似乎并不符合我理解的规则。 - djdd87
我并不是DDD方面的专家,但我理解领域对象需要代表/建模真实的对象和过程。因此,如果每个方法中都有存储库,我会感到不满意。 - Aliostad
+1,没错,我完全同意。我很高兴我们一直在使用方案1。 - djdd87

1

是的,伙计,第一个更好...

就好像我们以对象的形式思考一样...

将产品添加到列表中与产品存储库无关,它只应该获取产品。


产出实际上是产品,这是一个打字错误。 - Genius

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接