設計模式——裝飾模式

裝飾模式

定義

裝飾者模式又稱爲包裝(wrapper)模式。裝飾者模式對客戶端透明的方式擴展對象的功能,是繼承關係的一個替代方案。

模板

抽象構件(Component)角色:給出一個抽象接口,以規範準備接受附加責任的對象。
 具體構件(ConCreteComponent)角色:定義一個將要接受附加責任的類。
裝飾(Decorator)角色:持有一個構件(Component)對象的實例,並定義一個與抽象構件接口一致的接口。
 具體裝飾(ConcreteDecorator)角色:負責給構件對象“貼上”附加的責任。

裝飾模式模板

實例

a) 客戶端埋點:經常將回調接口再包裝一層,在包裝層完成埋點或者其它非主功能的輔助代碼
例: 對下載回調listener包裝一層,進行下載的埋點。

b) 添加額外的輔助功能: 某個異步回調接口,可能出現回調收不到的bug,這時想設計一種 帶自動超時功能的回調:
// 原listener

public interface IListener<T> {
    void onSuccess(T result);
    void onError(String errorCode, String errorDesc);
}

// 帶自動超時功能的listener

public class AutoTimeoutResultListener<T> extends AbstractAutoTimeout
        implements IListener<T> {

    private IListener<T> mListener;

    public AutoTimeoutResultListener(IListener<T> listener) {
        mListener = listener;
    }

    @Override
    public synchronized void onSuccess(T result) {
        mListener.onSuccess(result);
    }

    @Override
    public synchronized void onError(String errorCode, String errorDesc) {
       mListener.onError(errorCode, errorDesc);
    }

    @Override
    synchronized void onTimeout() {
        mListener.onError(Constants.ERROR_CODE_TIME_OUT, "IListener time out.");
    }
}

裝飾模式的簡化:

(1) 只有一個ConcreteComponent時,可以考慮去掉抽象的Component類,把Decorator作爲ConcreteComponent的子類。

(2) 如果只有一個ConcreteDecorator類,可以將Decorator類和ConcreteDecorator的責任合成一個類。

透明性要求:
裝飾模式對客戶端的透明性要求程序不要聲明Decorator類型的變量,而應該聲明Component接口變量。

半透明的裝飾模式:
純粹的裝飾模式已經很難找到了,裝飾模式的用意是在不改變接口的前提下,增強類的性能。在增強性能時,需要建立新的方法,但是純粹的裝飾模式無法通過Component調用新建立的方法,這時候需要破壞透明性,才能使用新方法。

半透明的裝飾模式是介於裝飾模式和適配器模式之間的,裝飾模式和適配器模式都是“包裝模式”,它們都通過封裝其他的對象達到設計的目的,但是邢臺有很大區別。

理想的裝飾模是在被裝飾對象進行功能增強時,要求具體的構件角色、裝飾角色的接口和抽象構件角色的接口完全一致。而適配器並不要求對原對象進行增強,但會改變對象的接口,以便和目標接口相符合。

透明性

優點

  1. 對原有代碼的侵入性很小,可以在不改變原有代碼結構的同時增加新的功能,如遇到緊急上線等情況不失爲一種好的解決方法。
  2. 可以在裝飾類中增加新的功能/增強原有的功能,也符合職責單一原則,裝飾類專門做某種處理(埋點/超時處理)

缺點

  1. 增加新的類
  2. 多層裝飾比較複雜,影響代碼的維護及可讀性

適用場景

  1. 需求開發緊急,添加新功能
  2. 普通的添加新功能也可以使用該種方法

其它實例:

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章