結(jié)構(gòu)型模式--代理模式&&適配器模式&&裝飾器模式

算是讀書筆記吧

極客時(shí)間--設(shè)計(jì)模式之美


代理模式和裝飾器模式的在實(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)系過于復(fù)雜的問題,借助面向接口的編程思想,通過組合來替代繼承。

  • 實(shí)現(xiàn)上

在不改變?cè)碱悾ɑ蚪斜淮眍悾┐a的情況下,由新的類和原始類需要實(shí)現(xiàn)相同的接口。


二者的區(qū)別性

二者的區(qū)別體現(xiàn)在想要對(duì)原始類附加的功能

代理模式

將功能直接轉(zhuǎn)交給代理類進(jìn)行實(shí)現(xiàn)。

偏重業(yè)務(wù)無關(guān),高度抽象,和穩(wěn)定性較高的場景。
由原始類指定代理類,對(duì)業(yè)務(wù)方隱藏代理類的存在。

比如對(duì)數(shù)據(jù)訪問功能添加日志,緩存。

裝飾器模式

給原始類添加增強(qiáng)功能。

偏重業(yè)務(wù)相關(guān),定制化訴求高,改動(dòng)較頻繁的場景。
由業(yè)務(wù)方指定裝飾類,依賴業(yè)務(wù)方的具體實(shí)現(xiàn)。

比如業(yè)務(wù)級(jí)別上對(duì)日志增加字段、數(shù)據(jù)的加工整理。

代理模式主要目的是控制訪問,而非加強(qiáng)功能。這是它跟裝飾器模式最大的不同


適配器模式

適配器模式與代理和裝飾器模式一樣,也是基于面向接口編程的特性,通過接口對(duì)不同的類進(jìn)行統(tǒng)一約束。

這里的統(tǒng)一,體現(xiàn)在:

  • 不同類的調(diào)用方式統(tǒng)一,更好的利用多態(tài)特性

// 使用適配器模式進(jìn)行改造
public interface ISensitiveWordsFilter { // 統(tǒng)一接口定義
  String filter(String text);
}

// 擴(kuò)展性更好,更加符合開閉原則,如果添加一個(gè)新的敏感詞過濾系統(tǒng),
// 這個(gè)類完全不需要改動(dòng);而且基于接口而非實(shí)現(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) {  //這里每個(gè)filter的filter方法內(nèi)部,包裹著真實(shí)實(shí)現(xiàn)
      maskedText = filter.filter(maskedText);
    }
    return maskedText;
  }
}

當(dāng)然,也有為了版本兼容而使用的適配器模式。將適配器實(shí)現(xiàn)的細(xì)節(jié),轉(zhuǎn)接給另一個(gè)類進(jìn)行實(shí)現(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)換為可兼容的接口,讓原本由于接口不兼容而不能一起工作的類可以一起工作。適配器模式有兩種實(shí)現(xiàn)方式:類適配器和對(duì)象適配器。其中,類適配器使用繼承關(guān)系來實(shí)現(xiàn),對(duì)象適配器使用組合關(guān)系來實(shí)現(xiàn)。
一般來說,適配器模式可以看作一種“補(bǔ)償模式”,用來補(bǔ)救設(shè)計(jì)上的缺陷。應(yīng)用這種模式算是“無奈之舉”,如果在設(shè)計(jì)初期,我們就能協(xié)調(diào)規(guī)避接口不兼容的問題,那這種模式就沒有應(yīng)用的機(jī)會(huì)了。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

友情鏈接更多精彩內(nèi)容