Spring中常见的设计模式——装饰者模式

一、装饰者模式的应用场景

  装饰者模式(Decorator Pattern)是指在不改变原有对象的基础上,将功能附加到对象上,提供了比继承更有弹性的方案(扩展原有对象的功能),属于结构型模式。装饰者模式适用于以下场景:

  • 扩展一个类的功能或给一个类添加附加职责。
  • 动态给一个对象天机功能,这些功能可以再动态的撤销。

  以做煎饼果子为例演示装饰者模式是怎么装的:

  首先做一个煎饼果子抽象:

public abstract class Battercake {
    protected abstract String getMsg();

    protected abstract Integer getPrice();
}

  然后,做一个基本的煎饼果子:

public class BaseBattercake extends Battercake{
    @Override
    protected String getMsg() {
        return "煎饼";
    }

    @Override
    protected Integer getPrice() {
        return 5;
    }
}

  创建扩展套餐的抽象装饰者:

public class BattercakeDecorator extends Battercake {
    //静态代理 委派
    private Battercake battercake;

    public BattercakeDecorator(Battercake battercake) {
        this.battercake = battercake;
    }

    @Override
    protected String getMsg() {
        return battercake.getMsg();
    }

    @Override
    protected Integer getPrice() {
        return battercake.getPrice();
    }
}

  创建加鸡蛋装饰类:

public class EggDecorator extends BattercakeDecorator {
    public EggDecorator(Battercake battercake) {
        super(battercake);
    }

    @Override
    protected String getMsg() {
        return super.getMsg() + "add an egg";
    }

    @Override
    protected Integer getPrice() {
        return super.getPrice() + 1;
    }
}

  客户端:

public class BattercakeTest {
    public static void main(String[] args) {
        //基本版
        Battercake battercake = new BaseBattercake();

        //加蛋
        battercake = new EggDecorator(battercake);

        //再加
        battercake = new EggDecorator(battercake);

        //跟静态代理区别在于静态代理不是is-a关系 晶体代理会做功能增强,使同一个职责变得不一样
        //装饰者模式更多考虑扩展
    }
}

二、装饰者模式和适配器模式对比

  装饰者模式和适配器模式都是包装模式(Wrapper Pattern),装饰者模式是一种特殊的代理模式,二者对比如下:

  装饰者模式 适配器模式
形式 是一种非常特别的适配器 没有层级关系,装饰者模式有层级关系
定义 装饰者和被装饰着实现同一接口,主要目的是为了扩展后依旧保留旧的oop关系 适配器和被适配这没有必然的关系,通常采用继承或代理的形式进行包装
关系 满足is-a关系 满足has-a关系
功能 注重覆盖、扩展 注重兼容、转换
设计 前置考虑 后置考虑

三、装饰模式在源码中的应用

  JDK中的I/O,如BufferReader,InputStream,OutputStream.Spring的缓存,myabtis的TransactionalCache(事物相关缓存):

public class TransactionalCache implements Cache {
    private static final Log log = LogFactory.getLog(TransactionalCache.class);
    private final Cache delegate;
    ...
    public TransactionalCache(Cache delegate) {
        this.delegate = delegate;
        ...   
    }
    ...
}

四、装饰者模式的优缺点

 优点:

  • 装饰者模式是继承的有力补充,比继承灵活,可以再不原有对象的情况下动态的给一个对象扩展功能,即插即用。
  • 使用不同的装饰类及这些装饰类的排列组合,可以实现不同的效果。
  • 装饰者模式完全符合开闭原则。

 缺点:

  • 动态装饰时,多层装饰会更复杂。
  • 增加复杂度,复杂度等等吧那些废话。

你可能感兴趣的:(Spring中常见的设计模式——装饰者模式)