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