2015-02-24 50 views
0

我想为我的域建立一个愿望清单功能。 我的变量是:建模聚合根或域服务?

  1. 不能添加产品已在愿望清单
  2. 您不能添加你自己的产品。

第二不变让我不知道 - 我应该模拟这项功能再造骨料(因为$ ownedProductIds的ORM是从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 
    } 
} 
+1

你能提供一个例子吗?也许我不明白。 – acid 2015-02-24 13:28:26

+0

@ guillaume31事实是,我没有仔细阅读代码,误解了拥有产品的概念,这基本上是你已经购买的产品。我认为产品有一个单一的所有者的概念,你不能购买你自己的产品。在这种情况下,模型可能会完全不同。不过,现在我认为'User'上的行为可能很好,直到发现更好的概念为止。如果存在争用,无状态服务不是一个可行的解决方案。 – plalx 2015-02-24 14:37:37

回答

0

由于User具有执行不变量所需的所有信息,所以我将它留在那里。我通常只在某个操作似乎不属于一个实体时才创建域服务(TransferMoney()方法不适用于Account类是此发布的子代)。

但请注意,您的模型目前非常简单。事实上,指定总计User可能是有意义的,但在真实情况下,您有可能会实现突破,彻底改变它。