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

Posted yingxiaocao

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了设计模式之装饰者设计模式相关的知识,希望对你有一定的参考价值。

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

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流,就是典型的装饰者设计模式

以上是关于设计模式之装饰者设计模式的主要内容,如果未能解决你的问题,请参考以下文章

设计模式之装饰者模式

设计模式之装饰者模式

Java设计模式之装饰者模式

JAVA设计模式之装饰者模式

设计模式之装饰者模式

JS设计模式之装饰者模式