2017-10-07 60 views
0

我想在这里使用装饰模式。 BaseCart是抽象类。购物车扩展了BaseCart并获得总价。现在我想在不改变现有代码的情况下给予总购物车价值的折扣。所以我创建了扩展BaseCart的CartDecorator,然后创建TotalDiscountCart,它将获得总金额,然后对其应用折扣。问题与装饰设计模式在java

现在我试图运行下面给出的单元测试没有给出正确的输出。产品被添加到购物车中,但是当Cart的getTotalPrice()方法被调用时,则productsWithQuantity为空。 是否应该添加值?它为什么是空的以及如何解决它?

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()); 
    } 

回答

1

你应该CartDecorator委托addProductcart。由于CartDecorator不能从子类BaseCart中获益,所以创建Cart接口也可能是有意义的。

请您详细说明一下,“CartDecorator创建购物车界面不会从BaseCart的子类中获益”。

您的BaseCart实际上做了两件事。一个是定义与购物车一起使用的界面(由addProductgetTotalPrice方法组成)。另一个是提供addProduct的基本实现,其填充productsWithQuantity地图。

现在a CartDecorator装饰另一个购物车。它(当然)应该实现与所有购物车相同的界面。但是对于CartDecorator,从BaseCart继承addProduct实施实际上会适得其反。由于CartDecorator可以委托addProduct到装饰车 - 因此它实际上并不需要自己productsWithQuantity地图等

这就是为什么它可能是有意义的定义Cart接口,如果你认为你需要一个基本的抽象实现像BaseCart。然后CartDecorator将实现Cart接口但不延伸BaseCart

+0

您能否详细说明一下,“CartDecorator创建购物车界面不会从BaseCart的子类中获益”。 – user1298426

+0

@ user1298426查看更新。 – lexicore