【问题标题】:Modelling aggregate root or domain service?建模聚合根或域服务?
【发布时间】:2015-02-24 09:46:23
【问题描述】:

我想为我的域建模愿望清单功能。 我的不变量是:

  1. 您无法添加愿望清单中已有的产品
  2. 您无法添加您拥有的产品。

第二个不变量让我想知道 - 我是否应该将此功能建模为重组聚合(在 ORM 之外,因为 $ownedProductIds 是从 UserProductRepository 获取的):

final class User extends EventSourcedAggregateRoot
{
    // ...

    /**
     * @param UserId           $userId
     * @param ObjectCollection $ownedProductIds
     * @param ObjectCollection $wishlistedProductIds
     * @return $this
     */
    public static function reconstituteFrom(
        UserId $userId,
        ObjectCollection $ownedProductIds,
        ObjectCollection $wishlistedProductIds
    )
    {
        $user = new User();
        $user->userId = $userId;
        $user->ownedProductIds = $ownedProductIds;
        $user->wishlistedProductIds = $wishlistedProductIds;

        return $user;
    }

    /**
     * @param Product $product
     * @throws ProductAlreadyPurchased Thrown when trying to add already bought product
     * @throws ProductAlreadyWishlisted Thrown when trying to add already wishlisted product
     */
    public function addProductToWishlist(Product $product)
    {
        $productId = $product->getId();

        if ($this->ownedProductIds->contains($productId)) {
            throw new ProductAlreadyPurchased($this->userId, $productId);
        }

        if ($this->wishlistedProductIds->contains($productId)) {
            throw new ProductAlreadyWishlisted($this->userId, $productId);
        }

        $this->apply(new ProductWishlisted($this->userId, $product));
    }

    // ...
}

或者更确切地说是创建一个无状态域服务:

final class Wishlist
{
    public function addProductToWishlist(Product $product, UserId $userId)
    {
        $ownedProductids = $this->userProductRepository->findProductsOfUser($userId);
        $wishlistedProductsIds = $this->userWishlistProductIdRepository->findProductsOfUser($userId);

        // business rules as in User class
    }
}

【问题讨论】:

  • 你能举个例子吗?也许我不明白。
  • @guillaume31 事实是我没有仔细阅读代码,误解了拥有一个产品的概念,基本上就是你已经买了哪些。我认为产品有一个单一的所有者概念,你不能购买自己的产品。在这种情况下,模型可能会完全不同。但是,现在我认为User 的行为可能很好,直到发现更好的概念。如果存在争用,无状态服务不是可行的解决方案。

标签: oop domain-driven-design


【解决方案1】:

由于User 拥有强制执行不变量所需的所有信息,因此我将其留在那里。我通常只在某些操作似乎不属于一个实体时才创建域服务(TransferMoney() 方法不适合 Account 类是这个的典型代表)。

请注意,您的模型目前非常简单。事实上,将聚合命名为 User 可能是有意义的,但在实际情况下,您可能会取得彻底改变它的突破。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-11-30
    • 1970-01-01
    相关资源
    最近更新 更多