Open netojoaobatista opened 10 years ago
Podemos extrair as implementações de iteração do carrinho para uma ProductCollection
? Assim será possível reaproveitar essa implementação sem que o Shopping\Order
dependa de uma instância de Shopping\Cart
. Afinal, quando uma Shopping\Order
é criada, o Shopping\Cart
deveria deixar de existir, correto?
Semanticamente falando, @danizord, um Shopping\Order
sempre vai depender de um Shopping\Cart
. Afinal, o que é um pedido, senão a finalização de um carrinho?
Veja, não estou dizendo que um ProductCollection
não é adequado. Só estou dizendo que a dependência entre Shopping\Order
e Shopping\Cart
existe por definição.
@netojoaobatista, ah sim, me expressei mal, minha intenção não é remover a dependência em sí, mas a composição.
O Shopping\Cart
é mutável, por isso eu acho que ele deveria ser descartado no momento da criação da Shopping\Order
. Depois que a compra foi finalizada, não podemos mais adicionar/remover produtos da compra.
Okay,
Agora, é mesmo necessário um ProductCollection? Não seria mais simples, seShopping\Order
apenas encapsular Shopping\Cart
?
@netojoaobatista A função da ProductCollection
seria desacoplar a Shopping\Order
do Shopping\Cart
, de forma que qualquer alteração no estado do Shopping\Cart
não seja refletida no estado do Shopping\Order
.
$cart = new Cart();
$cart->addItem(new Product(), 1);
$cart->addItem(new Product(), 1);
$order = new Order($cart);
$price = $order->getPrice();
$cart->addItem(new Product(), 1);
$this->assertEquals($price, $order->getPrice());
A pergunta permanece, @danizord. É mesmo necessário um ProductCollection
?
Uma vez que trabalhamos com referências para as instâncias, modificações em Shopping\Cart
afetarão a ProductCollection
que, por sua vez, afetará Shopping\Order
.
Vejo duas formas de se evitar esse problema:
Shopping\Cart
, conseguimos evitar que mudanças no carrinho, ou em um ProductCollection
, afetem o Shopping\Order
.Shopping\Order
observar Shopping\Cart
por mudanças, podemos disparar um \DomainException
, caso exista a tentativa de se modificar o estado do carrinho após criação de Shopping\Order
.@netojoaobatista Shopping\Cart
e Shopping\Order
não compartilhariam a mesma instância de ProductCollection
, cada um teria a sua própria coleção de produtos encapsulada. Porém, nós precisamos da mesma implementação de iterator nos dois lugares, daí a necessidade de uma ProductCollection
.
class Order
{
private $products;
public function __construct(Cart $cart)
{
$this->products = clone $cart->getProducts();
}
}
é isso, @danizord?
@gabrielsch sim sim, essa é uma das formas que o @netojoaobatista propôs para resolver o problema, que na minha opinião é a melhor forma, com prototype.
Durante a navegação, o usuário adiciona diversos
Shopping\Product
aoShopping\Cart
, com suas respectivas quantidades. Ao concluir a escolha e adição dos produtos, existe a opção por finalizar a compra, transformando umShopping\Cart
em umShopping\Order
.Enquanto um
Shopping\Cart
é apenas um agregador deShopping\Product
, umShopping\Order
envolve alguns comportamentos adicionais, como total da compra, descontos, taxas, etc. O design de umShopping\Order
deve ser de tal forma que esse participante possa reaproveitar as implementações para iteração dos itens do carrinho, adicionando os comportamentos específicos relacionados com o pedido e sua finalização.Como deve ser, então, o design de um
Shopping\Order
?Shopping\Cart
?Como implementar as possíveis opções de pagamento, entrega de mercadoria, descontos, etc, e como esses participantes devem interagir com o
Shopping\Order
?