2017-10-07 3 views
0

J'essaye d'employer le modèle de décorateur ici. BaseCart est une classe abstraite. Cart étend BaseCart et obtient le prix total. Maintenant, je veux donner une réduction sur la valeur totale du panier sans changer le code existant. J'ai donc créé CartDecorator, qui étend BaseCart, puis créé TotalDiscountCart, qui recevra le montant total, puis appliquera une réduction. Maintenant, j'essaie d'exécuter le test unitaire donné ci-dessous ne donne pas une sortie correcte. Le produit est ajouté au panier mais lorsque la méthode getTotalPrice() de Cart est appelée, alors productsWithQuantity est vide. Ne devrait-il pas avoir des valeurs ajoutées? Pourquoi est-il vide et comment le résoudre?Problème avec le modèle de conception de décorateur en java

public abstract class BaseCart { 


     Map<Product, Integer> productsWithQuantity = new HashMap<Product, Integer>(); 
     Double totalPrice = 0.0; 

     public void addProduct(Product product, Integer quantity){ 
      productsWithQuantity.put(product, quantity); 
     } 

     public abstract Double getTotalPrice(); 
    } 


    public class Cart extends BaseCart{ 

     @Override 
     public Double getTotalPrice() { 
      productsWithQuantity.forEach((product ,quantity)-> totalPrice = totalPrice + product.getUnitPrice() * quantity); 
      return totalPrice; 
     } 


    } 


public class CartDecorator extends BaseCart{ 

    BaseCart cart; 

    public CartDecorator(BaseCart cart) { 
     super(); 
     this.cart = cart; 
    } 

    @Override 
    public Double getTotalPrice() { 
     return this.cart.getTotalPrice(); 
    } 

} 

public class TotalDiscountCart extends CartDecorator{ 

    public TotalDiscountCart(BaseCart cart) { 
     super(cart); 
    } 

    @Override 
    public Double getTotalPrice() { 
     super.getTotalPrice(); 
     return totalPrice - (percentDiscount(10.0)); 

    } 

    private Double percentDiscount(Double i) { 
     return 0.1 * totalPrice; 
    } 


} 

    @Test 
    public void shouldGiveDiscountOf9() { 
     //Given 
     BaseCart cart = new TotalDiscountCart(new Cart()); 

     Product productDove = new Product("Dove soap", 30.0); 

     //when 
     cart.addProduct(productDove, 3); 

     // then 
     assertEquals(Double.valueOf(81.0),cart.getTotalPrice()); 
    } 

Répondre

1

Vous devez déléguer addProduct-cart dans CartDecorator. Il serait également logique de créer une interface Cart car CartDecorator ne bénéficie pas de la sous-classe BaseCart.

Pouvez-vous élaborer cette 'créer une interface Cart' car CartDecorator ne profite pas de la sous-classe BaseCart. '?

Votre BaseCart fait réellement deux choses. L'un est la définition d'une interface pour travailler avec des chariots (composé des méthodes addProduct et getTotalPrice). L'autre fournit une implémentation de base pour addProduct qui remplit la carte productsWithQuantity.

Maintenant, un CartDecorator décore un autre panier. Il (bien sûr) devrait implémenter la même interface que tous les chariots. Mais pour le CartDecorator, il est en fait contre-productif d'hériter de l'implémentation addProduct du BaseCart. Parce que CartDecorator pourrait déléguer addProduct au panier décoré - il ne fait pas besoin de sa propre carte productsWithQuantity etc.

C'est pourquoi il peut être judicieux de définir l'interface Cart et si vous pensez avoir besoin d'une implémentation abstraite de base comme BaseCart. Le CartDecorator implémenterait alors l'interface Cart mais ne s'étendrait pas BaseCart.

+0

Pouvez-vous élaborer cette 'créer une interface Cart' car CartDecorator ne profite pas de la sous-classe BaseCart. '? – user1298426

+0

@ user1298426 Voir la mise à jour. – lexicore