业务逻辑应该放在域还是服务中?

时间:2009-01-14 02:15:01

标签: domain-driven-design

假设您拥有域实体用户,并且您希望支持用户将商品添加到购物车的功能。现在,我们要确保购物车中的商品是唯一的,因此我们在User类中创建以下功能:

function AddItemToCart(Item item)
{
    // Add business logic to make sure item is unique
}

这很有效。但是,如果我们现在想要在项目添加到购物车时也通过电子邮件发送给用户呢?我们可以将它添加到AddItemToCart中,但它需要将一些IEmailer依赖项注入User类。

另一种方法是创建一个服务来处理这个事务(例如ShoppingCartService),它将执行业务逻辑并发送电子邮件。然而,这会导致一个相当贫乏的领域(即用户类只不过是getter / setter)

4 个答案:

答案 0 :(得分:4)

作为用户域逻辑一部分的逻辑应该留在用户中。这可能涉及或可能不涉及向用户实体注入服务。我认为这取决于该服务是否属于User类的业务逻辑,以及这是否符合您无处不在的语言。

我会这样写:

class ShoppingCartService
{
    private EmailService emailer;

    public void addItemToUserCart(User u, Item i)
    {
        u.addItemToCart(i);
        this.emailer.sendEmailTo(u, "Item " + i.toString() + " was added to your cart");
    }
}

This related question您可能会发现有用的讨论。

我还建议你尽量限制吸气剂和固定剂,以减少耦合。

答案 1 :(得分:2)

“然而,这会导致一个相当贫乏的领域(即用户类只不过是吸气者/制定者)”

用户不是整个域。

您有购物车,商品和复杂的Cart.add(),可将商品放入购物车。

那么如果User类看起来过于简单呢?

答案 2 :(得分:0)

保持方法不变,然后创建一个服务类来处理事务。当调用服务类方法时,您可以在那里注入电子邮件逻辑。

答案 3 :(得分:0)

在大型系统中,用户级最终会有很多不同类型的操作。这堂课可能会变得太大。为了避免这种情况,应该有其他类为用户做事。