2017-07-05 7 views
1

OOPとDDDの後にPHPでショッピングカートを作成しています。 CartItemInterfaceを実装しているCartItemインスタンスのさまざまなタイプ(Type1ProductItem、Type2ProductItemなど)のコレクションとして動作するShoppingCartクラスがあります。OOP - コレクション内の一意の識別子を管理する

ShoppingCartの内部コレクションのキーとして使用する一意の識別子を管理する最適な方法はありますか?

私の現在のソリューションは、タイプおよびIDに基づいて一意の識別子を返すCartItemInterfaceにおける "getPrimaryKey()" メソッドである:

するShoppingCart:

ShoppingCart->add($CartItem); 
ShoppingCart->doSomething($CartItem); 

:その結果

public function add(CartItemInterface $CartItem) { 
    $this->items[$CartItem->getPrimaryKey()] = $CartItem; 
} 
public function remove(CartItemInterface $CartItem) { 
    unset($this->items[$CartItem->getPrimaryKey()]); 
} 

しかし、この方法では、カートのすべてのアクション(add、remove、update ..)の前に、uriのパラメータに応じてCartItemを作成してから、関連するメソッドに渡す必要がありますShoppingCartの:

// type and id coming as parameters 
switch ($type) { 
    case 1 : $CartItem = new Type1ProductItem($id); break; 
    case 2 : $CartItem = new Type2ProductItem($id); break; 
    .... 
} 
ShoppingCart->doSomething($CartItem); 

これは私が重複したロジックを避けるために、工場を使用することができますよう大きな問題ではありませんが、一意の識別子(UID)がCartItemインスタンスの外に作成され、渡された場合、それはより実現可能なソリューションとなります最初に商品が追加されたときにShoppingCartに追加しますか?

ShoppingCart->add($UID, CartItemInterface $CartItem); 
ShoppingCart->doSomething($UID); // no need of CartItem instance here 

uidがCartItemインスタンスの外部で管理されているかどうかはわかりません。 あなたはどう思いますか? ソリューションの長所と短所は何ですか? ありがとうございます。

+1

'$ UID'を工場に渡します。作成した 'CartItemInterface'オブジェクトの' PK'フィールドを初期化するために使用します。 'ShoppingCart'のインターフェースを変更しないでください。 – axiac

+0

なぜ 'CartItemInterface'を' add'に渡す必要がありますか? productId、productType、quantity、priceのような必要なプロパティを渡すのはなぜですか? –

+0

shoppingCartクラスの中にcartItemの主キーは必要ないと思います。 なぜ単純に$ this-> items [] = $ CartItemを実行しないのですか? 私はcartItemは値オブジェクトでなければならないと思います。なぜなら、itemItemはアイテムの説明であり、アイテム自体ではないからです。それで本当にIDが必要ないのです –

答えて

2

一般に、独自のメソッドの外側に集約を変更するリスクがあるため、変更可能なオブジェクトを集約のインスタンスに渡すことはお勧めしません。オブジェクトを渡すことはできますが、Valueオブジェクトのように不変でなければなりません。

あなたの場合、CartItemInterfaceが可変オブジェクトである場合、それは良いことではありません。あなたはこのように、(そうValueオブジェクト)それらを不変にするか、それらを渡す代わりに、そのプロパティを渡す(およびそれらのプロパティも不変でなければならない)ではないする必要があります。

public function addItemToCart($productId, $productType, $quantity, $price) 

を次に、あなたが何かをする必要がある場合例えば数量を変更するためのカートアイテム、次にShoppingCart(集計)メソッドにカートアイテム識別子を渡します。その識別子はShoppingCart集計から得られます。集計項目をユーザーに表示し、必ずしもGUIDである必要はありません。また、グローバルにユニークなものである必要があります。集計内でユニークでなければならないため、ゼロベースのインデックスでも十分です。このようにして、Aggregateは自らのカート項目を識別する方法を決定し、Aggregateは担当し、Aggregateは自らのカート項目に当てはまる権限であり、Aggregateは他のユーザーから許可を求めることなくいつでもこれを変更できますシステムの一部。あなたはカートからアイテムを削除する必要がある場合たとえば、あなたは次のように実行します。

public function remove($cartItemIndex) { 
    unset($this->items[cartItemIndex]); 
} 

あなたは私が(彼らに値オブジェクトを作成することをお勧めのカート内のいくつかの行動を必要とする(コメントで)言ったので不変)し、必要に応じて(つまり、追加のローカルDTOクラスを作成する必要なくカートをユーザーに表示するときに)それらを渡すことができます。

+0

あなたの努力のために大変ありがとうございます。 私はあなたの提案を感謝し、彼らは質問の範囲を超えています。 もう一度、ありがとうございます。 –

+0

私は集団に関する自分の経験の一部を、彼らが非常に重要であると分かち合いました。 –

関連する問題