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

    科技2023-10-20  96

    一、情景:

    老王在卖的煎饼摊子开张了,主营产品有煎饼、鸡蛋、火腿。 问题: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总结
    装饰者模式同继承一样,可以扩展行为,这符合开闭原则,但是有一个不好的地方就是这样会到账设计中出现很多小对象,程序的复杂性会增加。装饰者可以不断的叠加,例如上述案例中,可以用完包装完鸡蛋后,继续包装鸡蛋、不断重复包装行为。
    Processed: 0.018, SQL: 8