2015-02-24 48 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可能是有意義的,但在真實情況下,您有可能會實現突破,徹底改變它。