• 设计模式之装饰者设计模式


    设计模式之装饰者设计模式

    1.定义:动态的将责任附加到对象上。想要扩展功能,装饰者是有别于继承的另外一种选择。就增加功能而言,装饰者模式比子类更加的灵活

    涉及到的设计原则:类应该对扩展开放,对修改关闭

    要点:1.装饰者和被装饰者有相同的超类型

          2.可以用一个或者多个装饰者包装一个对象

         3.既然装饰者和被装饰者有相同的超类型,所以在任何需要原始对象的场合,就可以使用装饰过的对象代替它

         4.装饰者可以在所委托的被装饰者之前或者之后,添加自己的行为,已达到特定的目的

     

    2.装饰者模式的重要组件

      包含4个:Component抽象组件、ConcreteComponent具体构件、Decorate装饰角色、ConcreteDecorateA具体的装饰角色

        Component抽象组件:可以是一个接口或者抽象类,就是定义我们最原始的对象

      ConcreteComponent具体构件:是Component抽象组件的实现。也是要装饰的对象

      Decorate装饰角色:一般是一个抽象类,实现接口或者抽象方法,它里面不一样有抽象的方法,但是里面必会有一个变量指向Component抽象构件

      ConcreteDecorate具体的装饰角色: 具体的装饰类,就是要装饰最原始对象的类

    3.装饰者模式基本类图

    基本代码:

    1.Component抽象组件

    public abstract class Component {
        // 要抽象的方式
        public abstract void operate();
    }
    View Code

    2.ConcreteComponent具体构件

    public class ConcreteComponent extends Component {
        // 具体的实现
        @Override
        public void operate() {
            System.out.println("做一些事情");
        }
    }
    View Code

    3.Decorate装饰角色

    public class Decorate extends Component {
    
        private Component component = null;
    
        // 通过构造函数传递被装饰者
        public Decorate(Component component) {
            this.component = component;
        }
    
        // 委托给被装饰者执行
        @Override
        public void operate() {
            this.component.operate();
        }
    }
    View Code

    4.ConcreteDecorate具体的装饰A角色

    public class ConcreteDecorateA extends Decorate {
        // 定义被装饰者
        public ConcreteDecorateA(Component component) {
            super(component);
        }
    
        // 定义自己的修饰方法
        public void method1() {
            System.out.println("方法1修饰");
        }
    
        @Override
        public void operate() {
            super.operate();
            this.method1();
        }
    }
    View Code

    ConcreteDecorate具体的装饰B角色

    public class ConcreteDecorateB extends Decorate {
        // 定义被装饰者
        public ConcreteDecorateB(Component component) {
            super(component);
        }
    
        // 定义自己的修饰方法
        public void method1() {
            System.out.println("方法2修饰");
        }
    
        @Override
        public void operate() {
            super.operate();
            this.method1();
        }
    }
    View Code

    5.测试类

    public class TestMain {
    
        @Test
        public void decorateDesignTest() {
            Component component = new ConcreteComponent();
            // 第一次修饰
            component = new ConcreteDecorateA(component);
            //第二次修饰
            component = new ConcreteDecorateB(component);
            //修饰后执行
            component.operate();
        }
    }
    View Code

    4.装饰者设计模式案例:

      90级封号斗罗,附加魂环

    1.创建一个魂师类(最原始的对象,也就是Component抽象组件)

    public interface HunShi {
    
         String getDescription();
    
         int getHunShiLevel();
    }
    View Code

    2.创建一个具体的对象(相当于ConcreteComponent组件)

    public class FengHaoDouLuo implements HunShi {
    
        @Override
        public String getDescription() {
            return "封号斗罗";
        }
    
        @Override
        public int getHunShiLevel() {
            return 0;
        }
    }
    View Code

    3.创建一个装饰者的抽象组件(相当于Decorate抽象组件)

    public abstract class HunLoop implements HunShi {
    
    }
    View Code

    可以在这一层,组合被装饰者

    4.创建具体的装饰者(相当于ConcreteDecorate组件)

    1.创建十年魂环

    public class TenYearHunLoop extends HunLoop {
    
        HunShi hunShi;
    
        public TenYearHunLoop(HunShi hunShi) {
            this.hunShi = hunShi;
        }
    
    
        @Override
        public String getDescription() {
            return hunShi.getDescription()+"白";
        }
    
        @Override
        public int getHunShiLevel() {
            return hunShi.getHunShiLevel()+10;
        }
    }
    View Code

    2.创建百年魂环

    public class BaiYearHunLoop extends HunLoop {
    
        private HunShi hunShi;
    
        public BaiYearHunLoop(HunShi hunShi) {
            this.hunShi = hunShi;
        }
    
        @Override
        public String getDescription() {
            return hunShi.getDescription()+"黄";
        }
    
        @Override
        public int getHunShiLevel() {
            return hunShi.getHunShiLevel()+10;
        }
    }
    View Code

    3.创建千年魂环

    public class QianYearHunLoop extends HunLoop {
    
        HunShi hunShi;
    
        public QianYearHunLoop(HunShi hunShi) {
            this.hunShi = hunShi;
        }
    
        @Override
        public String getDescription() {
            return hunShi.getDescription()+"紫";
        }
    
        @Override
        public int getHunShiLevel() {
            return hunShi.getHunShiLevel()+10;
        }
    }
    View Code

    4.创建万年魂环

    public class WangYearHunLoop extends HunLoop {
    
        HunShi hunShi;
    
        public WangYearHunLoop(HunShi hunShi) {
            this.hunShi = hunShi;
        }
    
        @Override
        public String getDescription() {
            return hunShi.getDescription()+"黑";
        }
    
        @Override
        public int getHunShiLevel() {
            return hunShi.getHunShiLevel()+10;
        }
    }
    View Code

    5.创建10万年魂环

    public class TenWangYearHunLoop extends HunLoop {
    
        HunShi hunShi;
    
        public TenWangYearHunLoop(HunShi hunShi) {
            this.hunShi = hunShi;
        }
    
        @Override
        public String getDescription() {
            return hunShi.getDescription()+"红";
        }
    
        @Override
        public int getHunShiLevel() {
            return hunShi.getHunShiLevel()+10;
        }
    }
    View Code

    6.创建一个魂骨

    public class BaZhuMaoHunGu implements HunShi {
    
        private HunShi hunShi;
    
        public BaZhuMaoHunGu(HunShi hunShi) {
            this.hunShi = hunShi;
        }
    
    
        @Override
        public String getDescription() {
            return hunShi.getDescription()+"八蛛魂骨";
        }
    
        @Override
        public int getHunShiLevel() {
            return hunShi.getHunShiLevel();
        }
    }
    View Code

    5.创建一个测试类

        @Test
        public void test001() {
            // 创建一个普通的封号斗罗
            HunShi hunShi = new FengHaoDouLuo();
            // 为封号斗罗添加魂环
            hunShi = new TenYearHunLoop(hunShi);
            hunShi = new BaiYearHunLoop(hunShi);
            hunShi = new BaiYearHunLoop(hunShi);
            hunShi = new QianYearHunLoop(hunShi);
            hunShi = new QianYearHunLoop(hunShi);
            hunShi = new WangYearHunLoop(hunShi);
            hunShi = new WangYearHunLoop(hunShi);
            hunShi = new WangYearHunLoop(hunShi);
            hunShi = new TenWangYearHunLoop(hunShi);
            log.info(hunShi.getDescription());
            // 添加外魂附骨
            hunShi = new BaZhuMaoHunGu(hunShi);
            System.out.println( hunShi.getDescription());
            System.out.println("等级"+hunShi.getHunShiLevel());
        }
    View Code

    运行结果,如下图所示:

    6.装饰者模式的优点

      1.装饰者类和被装饰者类可以独立发展,不会相互耦合

      2.装饰者模式是继承的一种替代方案,我们不管装饰多少层,返回的对象还是Component原始对象类型。

      3.继承是静态的给类添加功能,而装饰者设计模式是动态的给类添加功能

      4.扩展性非常好

    7.装饰者模式的缺点:

      1.装饰者模式如果装饰多层,那么类是比较复杂的。如果内层报错了,就比较麻烦。因此,应减少类的数量,以降低系统的复杂度

    8.装饰者模式的使用场景:

      1.需要扩展一个类的功能,或者给一个类附加功能

      2.需要给一个对象添加功能,这些功能,可以动态的进行撤销

      3.需要给一批的兄弟类加装功能的时候,当然首选装饰者模式,比如JDK的IO流,就是典型的装饰者设计模式

  • 相关阅读:
    JVM参数说明介绍
    使用Intellij IDEA的Bookmarks
    js中对小数取整
    idea 中pom.xml依赖版本号报错(报红,如下图所示)
    Springboot项目启动后访问不到Controller
    pringBoot Controller接收参数的几种常用方式
    Spring启动执行流程梳理
    SQL条件语句(IF, CASE WHEN, IF NULL)
    获取tomcat服务器上的部分日志
    Linux下 SpringBoot jar项目后台运行、查看、停用
  • 原文地址:https://www.cnblogs.com/yingxiaocao/p/13270132.html
Copyright © 2020-2023  润新知