在实体

时间:2015-12-09 10:07:50

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

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

如果我的域实体仅包含状态,并且在普遍存在的语言中与它们相关联的行为方法被放入单独的类中,那么这被归类为贫血或富域模型吗?

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

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);
    }
}

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

2 个答案:

答案 0 :(得分:1)

据我所知,托运人和订单是您域中的两个不同概念(非技术性)。如果是这种情况,将它们分开是正确的选择,因为您应该将您的域模型设计为尽可能接近现实世界。

答案 1 :(得分:0)

什么是托运人?您的域名专家是否经常谈论托运人?不同的托运人是否以不同方式发货?我怀疑在商店工作的人会谈论托运人。他们最多会谈论发货的员工。

我认为将他们分开可能'没关系,但托运人将成为域名服务。 DDD更多的是降低沟通障碍,而不是单一责任原则。在DDD中,我怀疑它是否适合您的域模型,原因很简单,域专家不会谈论它。他们会谈论发货。

你可能会做的就是这个

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

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

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

这样你可以组合DDD和SOLID。