• 设计模式之装饰者模式


    定义

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

    结构

    • 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)模式
    装饰器模式(装饰设计模式)详解
    研磨设计模式-书籍

  • 相关阅读:
    《设计模式》(精华集)
    TClientDataSet使用(二)
    害我查了半天的错误!av错误,小心Component对象使用Application当Owner
    释放自己
    最近在转C#
    TClientDataSet的使用技巧
    小心使用可修改的常量。
    指数函数和正弦函数相乘
    adb 常用命令
    win7下ie9设置无法保存的问题
  • 原文地址:https://www.cnblogs.com/strongmore/p/15256879.html
Copyright © 2020-2023  润新知