简体   繁体   English

Java中的Decorator设计模式问题

[英]Issue with Decorator design pattern in java

I am trying to use decorator pattern here. 我试图在这里使用装饰器模式。 BaseCart is abstract class. BaseCart是抽象类。 Cart extends BaseCart and gets total price. 购物车扩展了BaseCart并获得总价。 Now I want to give discount on total cart value without changing the existing code. 现在,我想在不更改现有代码的情况下提供购物车总价的折扣。 So I created CartDecorator which extends BaseCart and then created TotalDiscountCart which will get total amount and then apply discount on it. 因此,我创建了扩展BaseCart的CartDecorator,然后创建了TotalDiscountCart,它将获取总金额,然后对其应用折扣。

Now I am trying to run unit test given below is not giving correct output. 现在,我尝试运行以下给出的单元测试,但未给出正确的输出。 Product is added in cart but when Cart's getTotalPrice() method is called then productsWithQuantity is empty. 产品已添加到购物车中,但是当调用购物车的getTotalPrice()方法时,productsWithQuantity为空。 Shouldn't it have values added? 它不应该添加值吗? Why is it empty and how to solve it? 为什么它是空的以及如何解决呢?

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

You should delegate addProduct to cart in CartDecorator . 你应该委托addProductcartCartDecorator It would also probably make sense to create a Cart interface as CartDecorator does not profit from subclassing BaseCart . 创建Cart接口可能也很有意义,因为CartDecorator不能从BaseCart子类中BaseCart

Can you please elaborate this 'create a Cart interface as CartDecorator does not profit from subclassing BaseCart.'? 您能否详细说明一下“创建Cart界面,因为CartDecorator不能从SubCart的子类化中受益”。

Your BaseCart actually does two things. 您的BaseCart实际上执行两件事。 One is defining an interface to work with carts (consisting of addProduct and getTotalPrice methods). 一种是定义一个与购物车一起使用的接口(由addProductgetTotalPrice方法组成)。 The other is provide a basic implementation for addProduct which fills the productsWithQuantity map. 另一种是提供了一个基本的实现addProduct其填充productsWithQuantity地图。

Now a CartDecorator decorates another cart. 现在,一个CartDecorator装饰另一个购物车。 It (of course) should implement the same interface as all carts do. (当然)它应该实现与所有购物车相同的接口。 But for the CartDecorator it is actually counterproductive to inherit the addProduct implementation from the BaseCart . 但对于CartDecorator它实际上是适得其反继承addProduct从实现BaseCart Because CartDecorator could delegate addProduct to the decorated cart - so it actually does not need its own productsWithQuantity map etc. 由于CartDecorator可以委托addProduct到装饰车-因此它实际上并不需要自己productsWithQuantity地图等。

This is why it might make sense to define the Cart interface and if you think you need it a basic abstract implementation like BaseCart . 这就是为什么定义Cart接口以及如果您认为需要使用基本的抽象实现(如BaseCart The CartDecorator then would implement the Cart interface but not extend BaseCart . 然后, CartDecorator将实现Cart接口,但不扩展BaseCart

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM