裝飾模式
定義
裝飾者模式又稱爲包裝(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調用新建立的方法,這時候需要破壞透明性,才能使用新方法。
半透明的裝飾模式是介於裝飾模式和適配器模式之間的,裝飾模式和適配器模式都是“包裝模式”,它們都通過封裝其他的對象達到設計的目的,但是邢臺有很大區別。
理想的裝飾模是在被裝飾對象進行功能增強時,要求具體的構件角色、裝飾角色的接口和抽象構件角色的接口完全一致。而適配器並不要求對原對象進行增強,但會改變對象的接口,以便和目標接口相符合。
優點
- 對原有代碼的侵入性很小,可以在不改變原有代碼結構的同時增加新的功能,如遇到緊急上線等情況不失爲一種好的解決方法。
- 可以在裝飾類中增加新的功能/增強原有的功能,也符合職責單一原則,裝飾類專門做某種處理(埋點/超時處理)
缺點
- 增加新的類
- 多層裝飾比較複雜,影響代碼的維護及可讀性
適用場景
- 需求開發緊急,添加新功能
- 普通的添加新功能也可以使用該種方法
其它實例: