算是讀書筆記吧
極客時間--設(shè)計模式之美
代理模式和裝飾器模式的在實現(xiàn)上相同蹦玫,所以放在一起看撮胧。
以代理模式為例
// 代理模式的代碼結(jié)構(gòu)(下面的接口也可以替換成抽象類)
public interface IA {
void f();
}
public class A impelements IA {
public void f() { //... }
}
public class AProxy impements IA {
private IA a;
public AProxy(IA a) {
this.a = a;
}
public void f() {
// 新添加的代理邏輯
a.f();
// 新添加的代理邏輯
}
}
private void demo() {
IA a = AProxy(A.new())
a.f()
}
二者的相似性
-
目的上
主要解決繼承關(guān)系過于復雜的問題赡突,借助面向接口的編程思想午绳,通過組合來替代繼承癌佩。
-
實現(xiàn)上
在不改變原始類(或叫被代理類)代碼的情況下碌嘀,由新的類和原始類需要實現(xiàn)相同的接口。
二者的區(qū)別性
二者的區(qū)別體現(xiàn)在想要對原始類附加的功能
代理模式
將功能直接轉(zhuǎn)交給代理類進行實現(xiàn)傍念。
偏重業(yè)務無關(guān)矫夷,高度抽象,和穩(wěn)定性較高的場景憋槐。
由原始類指定代理類双藕,對業(yè)務方隱藏代理類的存在。
比如對數(shù)據(jù)訪問功能添加日志阳仔,緩存忧陪。
裝飾器模式
給原始類添加增強功能。
偏重業(yè)務相關(guān)驳概,定制化訴求高赤嚼,改動較頻繁的場景。
由業(yè)務方指定裝飾類顺又,依賴業(yè)務方的具體實現(xiàn)更卒。
比如業(yè)務級別上對日志增加字段、數(shù)據(jù)的加工整理稚照。
代理模式主要目的是控制訪問蹂空,而非加強功能。這是它跟裝飾器模式最大的不同
適配器模式
適配器模式與代理和裝飾器模式一樣果录,也是基于面向接口編程的特性上枕,通過接口對不同的類進行統(tǒng)一約束。
這里的統(tǒng)一弱恒,體現(xiàn)在:
- 不同類的調(diào)用方式統(tǒng)一辨萍,更好的利用多態(tài)特性
// 使用適配器模式進行改造
public interface ISensitiveWordsFilter { // 統(tǒng)一接口定義
String filter(String text);
}
// 擴展性更好,更加符合開閉原則返弹,如果添加一個新的敏感詞過濾系統(tǒng)锈玉,
// 這個類完全不需要改動;而且基于接口而非實現(xiàn)編程义起,代碼的可測試性更好拉背。
public class RiskManagement {
private List<ISensitiveWordsFilter> filters = new ArrayList<>();
public void addSensitiveWordsFilter(ISensitiveWordsFilter filter) {
filters.add(filter);
}
public String filterSensitiveWords(String text) {
String maskedText = text;
for (ISensitiveWordsFilter filter : filters) { //這里每個filter的filter方法內(nèi)部,包裹著真實實現(xiàn)
maskedText = filter.filter(maskedText);
}
return maskedText;
}
}
當然默终,也有為了版本兼容而使用的適配器模式椅棺。將適配器實現(xiàn)的細節(jié)犁罩,轉(zhuǎn)接給另一個類進行實現(xiàn)
/**
* Returns an enumeration over the specified collection. This provides
* interoperability with legacy APIs that require an enumeration
* as input.
*
* @param <T> the class of the objects in the collection
* @param c the collection for which an enumeration is to be returned.
* @return an enumeration over the specified collection.
* @see Enumeration
*/
public static <T> Enumeration<T> enumeration(final Collection<T> c) {
return new Enumeration<T>() {
private final Iterator<T> i = c.iterator();
public boolean hasMoreElements() {
return i.hasNext();
}
public T nextElement() {
return i.next();
}
};
}
適配器模式是用來做適配,它將不兼容的接口轉(zhuǎn)換為可兼容的接口两疚,讓原本由于接口不兼容而不能一起工作的類可以一起工作床估。適配器模式有兩種實現(xiàn)方式:類適配器和對象適配器。其中鬼雀,類適配器使用繼承關(guān)系來實現(xiàn)顷窒,對象適配器使用組合關(guān)系來實現(xiàn)。
一般來說源哩,適配器模式可以看作一種“補償模式”,用來補救設(shè)計上的缺陷鸦做。應用這種模式算是“無奈之舉”励烦,如果在設(shè)計初期,我們就能協(xié)調(diào)規(guī)避接口不兼容的問題泼诱,那這種模式就沒有應用的機會了坛掠。