結構型模式--代理模式&&適配器模式&&裝飾器模式

算是讀書筆記吧

極客時間--設計模式之美


代理模式和裝飾器模式的在實現上相同,所以放在一起看。

以代理模式爲例

// 代理模式的代碼結構(下面的接口也可以替換成抽象類)
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()
}

二者的相似性

  • 目的上

主要解決繼承關係過於複雜的問題,藉助面向接口的編程思想,通過組合來替代繼承。

  • 實現上

在不改變原始類(或叫被代理類)代碼的情況下,由新的類和原始類需要實現相同的接口。


二者的區別性

二者的區別體現在想要對原始類附加的功能

代理模式

在不改變原始類(或叫被代理類)代碼的情況下,通過引入代理類來給原始類附加功能。

你是一個優秀的歌手,只會唱歌這一件事,不擅長找演唱機會,談價錢,搭臺,這些事情你可以找一個經紀人幫你搞定,經紀人幫你做好這些事情你就可以安穩的唱歌了,讓經紀人做你不關心的事情這叫代理模式。

裝飾器模式

給原始類添加增強功能。

你老愛記錯歌詞,歌迷和媒體經常吐槽你沒有認真對待演唱會,於是你想了一個辦法,買個高端耳機,邊唱邊提醒你歌詞,讓你擺脫了忘歌詞的詬病,高端耳機讓你唱歌能力增強,提高了基礎能力這叫裝飾者模式。


適配器模式

適配器模式與代理和裝飾器模式一樣,也是基於面向接口編程的特性,通過接口對不同的類進行統一約束。

這裏的統一,體現在:

  • 不同類的調用方式統一,更好的利用多態特性

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

// 擴展性更好,更加符合開閉原則,如果添加一個新的敏感詞過濾系統,
// 這個類完全不需要改動;而且基於接口而非實現編程,代碼的可測試性更好。
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方法內部,包裹着真實實現
      maskedText = filter.filter(maskedText);
    }
    return maskedText;
  }
}

當然,也有爲了版本兼容而使用的適配器模式。將適配器實現的細節,轉接給另一個類進行實現

/**
 * 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();
    }
  };
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章