设计模式之装饰者模式

定义

动态地给一个对象添加一些额外的功能,就增加功能来说,装饰者模式比生成子类更为灵活。
如我们生活中的早餐煎饼,可以加鸡蛋,加香肠,加蔬菜,可以很灵活的组合。

结构

  • Component,抽象组件,定义为一个接口来规范被装饰的对象。
  • ConcreteComponent,具体的组件对象,实现组件接口,通常就作为被装饰的对象。
  • Decorator,抽象装饰者,所有装饰者的父类,内部持有一个被装饰的对象。
  • ConcreteDecorator,具体的装饰者对象,负责实现增强被装饰对象的功能。

简单实现

抽象组件

public interface Component {

  void operation();
}

具体组件

public class ConcreteComponent implements Component {

  @Override
  public void operation() {
    System.out.println("ConcreteComponent operation()");
  }
}

抽象装饰者

public abstract class Decorator implements Component {

  protected Component component;

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

具体装饰者

public class ConcreteDecorator extends Decorator {

  public ConcreteDecorator(Component component) {
    super(component);
  }

  @Override
  public void operation() {
    component.operation();
    System.out.println("ConcreteDecorator operation()");
  }
}

另一个装饰者

public class ConcreteDecorator2 extends Decorator {

  public ConcreteDecorator2(Component component) {
    super(component);
  }

  @Override
  public void operation() {
    component.operation();
    System.out.println("ConcreteDecorator2 operation()");
  }
}

客户端

public class Client {

  public static void main(String[] args) {
    Component component = new ConcreteComponent();
    //装饰
    Component decorator = new ConcreteDecorator(component);
    //再装饰一次
    Component decorator2 = new ConcreteDecorator2(decorator);
    decorator2.operation();
  }

}

输出结果为

ConcreteComponent operation()
ConcreteDecorator operation()
ConcreteDecorator2 operation()

装饰者模式在JDK和Spring中的实现

JDK中的实现

JDK中的IO流

InputStream类似于装饰者模式中的Component抽象组件接口,
ByteArrayInputStream类似于ConcreteComponent具体组件,
FilterInputStream类似于Decorator抽象装饰者,
BufferedInputStream类似于ConcreteDecorator具体装饰者。

Spring中的实现

Spring中的TransactionAwareCacheDecorator,从名称就可以看出使用了装饰者模式

总结

优点

  1. 相比继承更加的灵活,在不改变原有对象的情况下,动态地给一个对象扩展功能。
  2. 通过多次装饰,可以组合出功能更加强大的对象。

缺点

  1. 会产生很多装饰类,增加了系统复杂度。

本质

装饰者模式的本质是动态组合,动态是手段,组合是目的。通过对象组合来实现为被装饰对象增加功能的目的。

使用场景

  1. 在不影响其他对象的情况下,动态、透明的给对象增强功能。
  2. 当不能使用继承的方式来扩展功能时。

和代理模式的区别

装饰者模式(左边)和代理模式(右边)在结构上很相似,但两种模式面向的功能扩展面是不同的。

  • 装饰者模式本质为动态组合,强调自身功能的扩展
  • 代理模式本质为控制对象访问,强调对过程的控制

以小明想租房为例,以装饰者模式来思考就是小明自己要增加查找房源、联系房东等功能扩展,以代理模式来思考就是小明直接找中介,让中介查找房源、联系房东。

参考

大战设计模式【3】—— 装饰模式
大战设计模式(第二季)【4】———— 从源码看装饰者模式
设计模式——装饰者模式
设计模式(九)——装饰者模式(io源码分析)
设计模式的征途—10.装饰(Decorator)模式
装饰器模式(装饰设计模式)详解
研磨设计模式-书籍

posted @ 2021-09-12 10:29  strongmore  阅读(59)  评论(0编辑  收藏  举报