我想在这里使用装饰模式。 BaseCart是抽象类。购物车扩展了BaseCart并获得总价。现在我想在不改变现有代码的情况下给出购物车总价值的折扣。所以我创建了CartDecorator,它扩展了BaseCart,然后创建了TotalDiscountCart,它将获得总金额,然后对其应用折扣。
现在我正在尝试运行下面给出的单元测试没有给出正确的输出。产品添加到购物车中但是当调用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());
}
答案 0 :(得分:1)
您应该将addProduct
委托给cart
中的CartDecorator
。创建Cart
接口可能也是有意义的,因为CartDecorator
不会从子类BaseCart
中获利。
请你详细说明'创建购物车界面,因为CartDecorator不会从子类化BaseCart中获利。'?
你的BaseCart
实际上做了两件事。一个是定义使用推车的界面(由addProduct
和getTotalPrice
方法组成)。另一个是为addProduct
提供填充productsWithQuantity
地图的基本实现。
现在CartDecorator
装饰另一辆车。它(当然)应该实现与所有购物车相同的界面。但对于CartDecorator
而言,从addProduct
继承BaseCart
实施方式实际上会适得其反。因为CartDecorator
可以将addProduct
委托给装饰的购物车 - 所以它实际上不需要自己的productsWithQuantity
地图等。
这就是为什么定义Cart
接口可能是有意义的,如果您认为需要它,则需要一个基本的抽象实现,如BaseCart
。 CartDecorator
然后会实现Cart
接口,但不会扩展BaseCart
。