【问题标题】:Should business logic be placed in the domain or the services?业务逻辑应该放在领域还是服务中?
【发布时间】:2009-01-14 02:15:00
【问题描述】:

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

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

这很好用。但是,如果我们现在还想在将商品添加到购物车时向用户发送电子邮件怎么办?我们可以将它添加到 AddItemToCart 中,但它需要将某种 IEmailer 依赖项注入到 User 类中。

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

【问题讨论】:

  • 如果站点管理员按顺序打电话会怎样?您确定 User.AddItemToCart 在这种情况下是正确的设计吗?

标签: domain-driven-design


【解决方案1】:

作为用户域逻辑一部分的逻辑应该留在用户中。这可能涉及也可能不涉及向用户实体注入服务。我认为这取决于服务是否是 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 的讨论可能对您有帮助。

我还建议您尽可能限制 getter 和 setter 的范围以减少耦合。

【讨论】:

    【解决方案2】:

    “然而,这导致了一个相当贫乏的领域(即 User 类只不过是 getter/setter)”

    用户不是整个域。

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

    如果 User 类看起来很简单怎么办?

    【讨论】:

      【解决方案3】:

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

      【讨论】:

        【解决方案4】:

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

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2014-02-24
          • 2011-08-01
          • 1970-01-01
          • 1970-01-01
          • 2012-05-27
          • 2023-04-07
          • 1970-01-01
          相关资源
          最近更新 更多