《设计模式(三)之——装饰者模式》

一、情景:

老王在卖的煎饼摊子开张了,主营产品有煎饼、鸡蛋、火腿。
问题:1、有顾客想买加了鸡蛋的煎饼、或者加了火腿、鸡蛋的煎饼,那么该如何改造呢?

在这里插入图片描述

二、情景后续

设计模式大佬、推荐他用装饰者模式,进行包装、包装出带有鸡蛋的煎饼

在这里插入图片描述

三、装饰者模式(Decorator)

  • 定义:动态的将责任附加到对象上若老扩展功能,装饰者提供老比继承更有弹性的替代方案
  • 重要组件
  • Component 被包装的原始组件
  • Decorator 实现与原始组件相同的接口,并且组合了一个原始组件的引用

四、代码演示

4.1类图

在这里插入图片描述

4.2 煎饼、鸡蛋、火腿公共接口(Component)
/**
 * @author liuzihao
 * @create 2020-10-07-11:45
 * 煎饼摊子基本接口
 */
public interface JbComponent {
    
    
    /**
     * 描述
     * @return
     */
    public String desc();

    /**
     * 价格
     * @return
     */
    public BigDecimal price();
}
4.3 各自的实现(ConcreteComponent)
/**
 * @author liuzihao
 * @create 2020-10-07-11:48
 * 鸡蛋
 */
public class JbComponenteEgg implements JbComponent {
    
    
    @Override
    public String desc() {
    
    
        return "鸡蛋";
    }

    @Override
    public BigDecimal price() {
    
    
        return new BigDecimal("1");
    }
}

/**
 * @author liuzihao
 * @create 2020-10-07-11:47
 */
public class JbComponentPancakes implements  JbComponent{
    
    
    @Override
    public String desc() {
    
    
        return "煎饼";
    }

    @Override
    public BigDecimal price() {
    
    
        return new BigDecimal(2);
    }
}
/**
 * @author liuzihao
 * @create 2020-10-07-11:48
 */
public class JbComponenthHotDog implements JbComponent {
    
    
    @Override
    public String desc() {
    
    
        return "火腿";
    }

    @Override
    public BigDecimal price() {
    
    
        return new BigDecimal(1);
    }
}

4.4 装饰者——带有鸡蛋煎饼(ConcreteDecoratoerA)

/**
 * @author liuzihao
 * @create 2020-10-07-11:51
 */
public class DecoratorPancakesWithEgg implements JbComponent {
    
    
    private JbComponent jbComponent;

    public DecoratorPancakesWithEgg(JbComponent jbComponent) {
    
    
        this.jbComponent = jbComponent;
    }
    @Override
    public String desc() {
    
    
        return jbComponent.desc() + "\t" + "加鸡蛋";
    }

    @Override
    public BigDecimal price() {
    
    
        return jbComponent.price().add(BigDecimal.ONE);
    }
}
4.5 装饰者——带有鸡蛋、火腿的煎饼(ConcreteDecoratoerB)
/**
 * @author liuzihao
 * @create 2020-10-07-11:54
 */
public class DecoratorPancakesWithHotDog implements JbComponent{
    
    
	// 传入已经加了鸡蛋的煎饼
    private JbComponent jbComponent;

    public DecoratorPancakesWithHotDog(JbComponent jbComponent) {
    
    
        this.jbComponent = jbComponent;
    }
    @Override
    public String desc() {
    
    
        return jbComponent.desc() +"\t" + "加热狗";
    }

    @Override
    public BigDecimal price() {
    
    
        return jbComponent.price().add(BigDecimal.ONE);
    }
}
4.6 代码测试
public class DemoMain {
    
    
    public static void main(String[] args) {
    
    
        JbComponent jbComponent1 = new JbComponenthHotDog();
        System.out.println("卖" + jbComponent1.desc() + "\t 价格" +jbComponent1.price());
        JbComponent jbComponent2 = new JbComponenteEgg();
        System.out.println("卖" + jbComponent2.desc() + "\t 价格" +jbComponent2.price());
        JbComponent jbComponent3 = new JbComponentPancakes();
        System.out.println("卖" + jbComponent3.desc() + "\t 价格" +jbComponent3.price());

        System.out.println("==开始卖包装产品==");
        JbComponent jbComponent4 = new DecoratorPancakesWithEgg(jbComponent3);
        System.out.println("卖" + jbComponent4.desc() + "\t 价格" +jbComponent4.price());
        JbComponent jbComponent5 = new DecoratorPancakesWithEgg(jbComponent4);
        System.out.println("卖" + jbComponent5.desc() + "\t 价格" +jbComponent5.price());


    }
}

在这里插入图片描述

五、小结

5.1改造之后的煎饼摊子

在这里插入图片描述

5.2总结
  • 装饰者模式同继承一样,可以扩展行为,这符合开闭原则,但是有一个不好的地方就是这样会到账设计中出现很多小对象,程序的复杂性会增加。
  • 装饰者可以不断的叠加,例如上述案例中,可以用完包装完鸡蛋后,继续包装鸡蛋、不断重复包装行为。

猜你喜欢

转载自blog.csdn.net/weixin_43732955/article/details/108944854