【问题标题】:Delegating Domain Model Behaviour outside of Entity在实体之外委托领域模型行为
【发布时间】:2016-03-14 13:27:13
【问题描述】:

我正在尝试实施领域驱动设计 (DDD),同时使用 SOLID 设计原则,但有以下问题:

如果我的领域实体仅包含状态,并且在通用语言中与它们相关联的行为方法被放置在单独的类中,这是否会归类为贫乏领域模型或富领域模型?

例如,不要在我的实体上使用它:

class Order
{
    public virtual void Ship();
}

我实际上已将其分解为一个单独的 OO 类:

class Shipper
{
    public virtual void Ship(Order order);
}

在我看来,这仍然是在“模型”内部,而不是服务/应用层,因此我相信这仍然是一个丰富的领域模型。

但是,我可以委托检索我的订单并将其运送到服务层的调用,如下所示:

class OrderService
{
    //private member construction ommitted for brevity
    Repository _repository;
    ShipOrder _shipper;
    public void Ship(int orderId)
    {
        Order order = _repository.GetOrder(orderId);
        _shipper.Ship(order);
    }
}

未在域实体内部实现行为逻辑的原因是,实现它会违反单一职责原则,因为我的实体的职责是在我的域中维护和存储状态。但是,我对此的看法可能是主观的。

【问题讨论】:

  • 问问自己,发货意味着什么?它如何影响系统的状态?需要强制执行哪些不变量以及在运输过程中发挥作用的其他组件(例如外部系统)?最后,您是否应该使用域服务或将行为放在 AR 上可能会变得很清楚。

标签: entity domain-driven-design behavior service-layer


【解决方案1】:

什么是托运人?您的领域专家经常谈论托运人吗?不同的托运人会以不同的方式运送订单吗?我怀疑在商店工作的人会谈论托运人。充其量他们会谈论运送订单的员工。

我认为将它们分开“可能”很好,但托运人将是一项域服务。 DDD 更多的是降低沟通障碍,而不是遵循单一责任原则。在 DDD 中,我怀疑它是否适合您的领域模型,原因很简单,领域专家不会谈论它。他们会谈论运送订单。

你可能会这样做

class Order {
      public void Ship() {
          IOCContainer.Resolve<IShippingService>.ShipOrder(this);
      }
 }

现在您可以将所有实际逻辑放入运输服务中(它实现了 IshippingService 接口)。这也解决了单一职责原则。如果你读过'uncle bob's cmets 关于单一责任原则的内容,那么不仅仅是做一件单一的事情,而是有一个改变的理由。 https://blog.8thlight.com/uncle-bob/2014/05/08/SingleReponsibilityPrinciple.html

如果我像这样实现我的运输逻辑,我希望我的这部分代码完全没有理由更改,(因为运输过程中的更改不会位于此处,而是位于 ShippingService 中)。

这样你可以结合 DDD 和 SOLID。

【讨论】:

  • 我能做些什么来改进这个答案?
【解决方案2】:

据我了解,Shipper 和 Order 是您领域中的两个不同概念(非技术上)。如果是这种情况,将它们分开是正确的选择,因为您应该将域模型设计得尽可能接近真实世界。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2023-03-07
    • 2015-12-30
    • 1970-01-01
    • 2011-07-16
    • 1970-01-01
    • 2013-03-10
    • 1970-01-01
    • 2010-12-20
    相关资源
    最近更新 更多