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;
        ...   
    }
    ...
}

四、裝飾者模式的優缺點

 優點:

  • 裝飾者模式是繼承的有力補充,比繼承靈活,可以再不原有對象的情況下動態的給一個對象擴展功能,即插即用。
  • 使用不同的裝飾類及這些裝飾類的排列組合,可以實現不同的效果。
  • 裝飾者模式完全符合開閉原則。

 缺點:

  • 動態裝飾時,多層裝飾會更復雜。
  • 增加復雜度,復雜度等等吧那些廢話。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM