建模聚合根或域服务?

时间:2015-02-24 09:46:24

标签: oop domain-driven-design

我想为我的域名建立一个愿望清单功能。 我的不变量是:

  1. 您无法添加已列入愿望清单的产品
  2. 您无法添加自己拥有的产品。
  3. 第二个不变量让我想知道 - 我是否应该将此功能建模为重构Aggregate(因为从UserProductRepository获取$ ownedProductIds而在ORM之外):

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

1 个答案:

答案 0 :(得分:0)

由于User拥有强制执行不变量所需的所有信息,我会把它留在那里。我通常只在某些操作似乎不属于一个实体时才创建域服务(TransferMoney()方法中不适合Account类的方法就是这个问题的候选版本。)

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