装饰器模式

装饰器模式

装饰器模式:动态的为一个实例增加额外的功能,装饰器为通过继承来进行功能扩展提供了另一种途径。

当通过继承父类来实现功能的扩展不太现实的时候,装饰器模式是一种很好的方式。

装饰器模式有两个显著的优点:

优点

  • 优点1:相比静态的继承父类来达到扩展功能,装饰器模式提供更加灵活的方式来增加额外的功能,装饰器模式能够在运行时动态的增加或者减少功能(一次或者多次);
  • 优点2:避免了功能类在继承结构上膨胀;相比与一开始就尝试支持所有可预见的功能,从而设计了一个非常复杂的、自定义的类的方式,装饰器模式则是先定义一个简单的类,然后不断的用装饰器装饰增加功能;由于系统能够自由组合不同的装饰器来达到功能的组合、扩展,因此相比于继承,在子类中就不太会出现冗余的功能;

缺点:由于装饰器模式中的装饰器类仅仅是在某一方面不同,这样在进行复杂的装饰的时候,会产生特别多的小的、比较像的实例对象(装饰器)。

装饰器模式含有几部分:

  • Component:定义了能够动态增加功能的对象的接口;
  • ConcreteComponent:Component的实现类
  • Decorator:持有一个需要被装饰的实例的引用(Component引用),接口遵循Component,满足里氏替换原则;
  • ConcreteDecorator:Decorator的实现类;

JDK里面的InputStream、BufferedInputStream 、DataInputStream、FileInputStream等都是利用装饰器模式。

装饰器模式从某种程度和代理模式相仿,但是两者还是有些细微的区别:

  1. 装饰器模式关注的是动态增加对象实例的功能;而代理模式关注的则是被代理对象访问的控制;
  2. 装饰器模式是增加类似的功能,是对被装饰类的功能增加;而代理模式则是代理增加非类似的功能

如果用户更关注的的是装饰器带来的功能,则用装饰器模式;而用户更关注的是原来的被代理类的功能,则使用代理模式。

UML类图

这里写图片描述

实例


public interface Component {
    void operation();
}

public class ConcreteComponent implements Component {

    @Override
    public void operation() {
        // TODO Auto-generated method stub
        System.out.println("ConcreteComponent: operation");
    }
}


public abstract class Decorator implements Component {
    Component component;

    public Decorator(Component component) {
        this.component = component;
    }
}


public class DecoratorA extends Decorator {

    public DecoratorA(Component component) {
        super(component);
        // TODO Auto-generated constructor stub
    }

    @Override
    public void operation() {
        // TODO Auto-generated method stub
        addtionalOperationA();//decorate operation
        this.component.operation();
    }

    public void addtionalOperationA() {
        System.out.println("addtionalOperationA");
    }

}

public class DecoratorB extends Decorator {

    public DecoratorB(Component component) {
        super(component);
        // TODO Auto-generated constructor stub
    }

    @Override
    public void operation() {
        // TODO Auto-generated method stub
        addtionalOperationB();
        this.component.operation();
    }

    public void addtionalOperationB() {
        System.out.println("addtionalOperationB");
    }

}


public class Main {

    public static void main(String[] args) {
        // TODO Auto-generated method stub
        Component component = new ConcreteComponent();
        //开始装饰
        component = new DecoratorA(component);
        component.operation();//仅仅被A装饰
        System.out.println("======");
        component = new DecoratorB(component);
        component.operation();//被B A同时装饰
    }
}

References

  1. 《设计模式:可复用面向对象软件的基础》
posted @ 2018-04-03 16:44  Spground  阅读(129)  评论(0编辑  收藏  举报