美文网首页
设计模式(八)-- 装饰器模式

设计模式(八)-- 装饰器模式

作者: 信仰年輕 | 来源:发表于2018-11-30 18:22 被阅读0次

    源代码
    GitHub源代码

    1.本文目标

    本文目标是为了让大家认识并理解装饰器模式

    2.基本套路

    定义:在不改变原有对象的基础之上,将功能附加到对象上
    类型:结构型
    选择关键点:添加的功能是否需要动态组装
    设计原则:遵循迪米特、单一职责、开闭原则,破坏里氏替换,体现功能复用
    使用概率:99.99999%
    难度系数:中

    3.适用场景

    1.扩展一个类的功能或给一个类添加附加职责
    2.动态的给一个对象添加功能,这些功能可以再动态的撤销

    4.使用步骤

    用具体的栗子更容易说明问题,继续往下看

    5.举个栗子

    我们用具体的代码去更好的理解这个设计模式

    5.1栗子说明

    • 背景:公司的小伙伴小王饿了,想买个煎饼
    • 目的:不仅仅是吃个煎饼,他还想加蛋,加烤肠,希望用装饰器模式实现

    5.2使用步骤

    实现代码如下:
    步骤1.创建抽象的实体类(抽象的煎饼)

    public abstract class ABatterCake {
        public abstract String getDesc();
        public abstract int cost();
    }
    

    步骤2.创建具体的实体类(具体的煎饼)继承抽象的实体类

    public class BatterCake extends  ABatterCake {
        @Override
        public String getDesc() {
            return "煎饼";
        }
    
        @Override
        public int cost() {
            return 8;
        }
    }
    

    步骤3.创建抽象的装饰类,继承抽象的实体类(抽象的煎饼)

    public class AbstractDecorator  extends ABatterCake{
        private ABatterCake mBatterCake;//抽象的煎饼,当然也可以传具体的煎饼
        public AbstractDecorator(ABatterCake mBatterCake) {
            this.mBatterCake = mBatterCake;
        }
        @Override
        public String getDesc() {
            return this.mBatterCake.getDesc();
        }
    
        @Override
        public int cost() {
            return this.mBatterCake.cost();
        }
    }
    

    步骤4. 创建具体的装饰类(鸡蛋装饰类),继承抽象的装饰类

    public class EggDecorator extends AbstractDecorator {
    
        public EggDecorator(ABatterCake mBatterCake) {
            super(mBatterCake);
        }
    
        @Override
        public String getDesc() {
            return super.getDesc()+"加一个鸡蛋";
        }
    
        @Override
        public int cost() {
            return super.cost()+1;
        }
    }
    

    步骤5. 创建具体的装饰类(烤肠装饰类),继承抽象的装饰类

    public class SausageDecorator extends AbstractDecorator {
        public SausageDecorator(ABatterCake mBatterCake) {
            super(mBatterCake);
        }
    
        @Override
        public String getDesc() {
            return super.getDesc()+"加一个烤肠";
        }
    
        @Override
        public int cost() {
            return super.cost()+2;
        }
    }
    

    步骤6. 测试

     public static void main(String[] args) {
            ABatterCake batterCake;
            //煎饼
            batterCake = new com.yadong.pattern.structural.decorator.v2.BatterCake();
            //加蛋
            batterCake = new EggDecorator(batterCake);
            //在加蛋
            batterCake = new EggDecorator(batterCake);
            //加个烤肠
            batterCake = new SausageDecorator(batterCake);
            /**
             * 输出结果:
             * 8+1+1+2=12块钱
             * 煎饼加一个鸡蛋加一个鸡蛋加一个烤肠 销售价格:12
             */
            System.out.println(batterCake.getDesc()+" 销售价格:"+batterCake.cost());
    
    
            /**
             * 另外一种写法,连起来写
             * 输出结果:
             * 煎饼加一个鸡蛋加一个烤肠加一个烤肠 销售价格:13
             * 煎饼+蛋+烤肠+烤肠
             * 8+1+2+2=13块钱
             */
            SausageDecorator sausageBatterCake= new SausageDecorator(new SausageDecorator(new EggDecorator(new BatterCake())));
            System.out.println(sausageBatterCake.getDesc()+" 销售价格:"+sausageBatterCake.cost());
      }
    

    6.优点

    • 继承的有力补充,比继承灵活,不改变原有对象的情况下给一个对象扩展功能
    • 通过使用不同装饰类以及这些装饰类的排列组合,可以实现不同效果
    • 符合开闭原则

    7.缺点

    • 会出现更多的代码,更多的类,增加程序复杂性
    • 动态装饰时,多层装饰会更复杂

    8.总结

    本文只是对装饰模式进行一个分享,接下来会从创建型模式,结构型模式,行为型模式,这三大类展开一个系列分享,大家可以持续进行关注,信仰年輕的设计模式,蟹蟹啦。

    相关文章

      网友评论

          本文标题:设计模式(八)-- 装饰器模式

          本文链接:https://www.haomeiwen.com/subject/xszhcqtx.html