java設計模式4.適配器模式、裝飾器模式

  • 適配器模式

把一個類的接口變換成客戶端所期待的另外一種接口,從而使本來因接口不匹配而沒法在一塊兒工做的兩個類可以工做。java

1. 類的適配器模式api

  • 目標角色:指望的接口,對於類的適配器模式,此角色不能夠是具體類。
  • 源角色:須要適配的接口。
  • 適配器角色:把源接口轉換成目標接口,此角色必須是具體類。
public interface Target { void fun2(); }
public class Adaptee { public void fun1(){ } }
// 適配器Adapter擴展了Adaptee,同時也實現了接口Target。這樣Adapter的類型是Adaptee同時也提供Target要求的方法。
public class Adapter extends Adaptee implements Target { @Override public void fun2() { // TODO Auto-generated method stub
 } }

2. 對象的適配器模式緩存

  • 目標角色:指望的接口,能夠是具體或抽象的類。
  • 源角色: 須要適配的接口。
  • 適配器角色:把源接口轉換成目標接口,此角色必須是具體類。
public class Adapter implements Target { private Adaptee adaptee; public Adapter(Adaptee adaptee){ this.adaptee = adaptee; } public void fun1(){ adaptee.fun1(); } @Override public void fun2() { // TODO Auto-generated method stub
 } }

能夠看出,對象適配器與類適配器的區別是使用對象組合代替了類型繼承。這樣一個適配器能夠把多種不一樣的源適配器到同一個目標。但與類適配器相比,要想置換源類的方法就不太容易,若是必定要置換,能夠先作好一個源類的子類置換掉方法,而後將子類看成真正的源進行適配。不過要是想增長一些新的方法則很方便,並且新增長的方法能夠同時適用於全部的源。

ide

  • 裝飾器模式

裝飾模式以對客戶端透明的方式擴展對象的功能,是繼承關係的一個替代方案。使用原來被裝飾的類的一個子類的實例,把客戶端的調用委派到被裝飾類。this

  • 抽象構建角色:給出一個抽象接口,以規範準備接收附加責任的對象。
  • 具體構建角色:定義一個將要接收附加責任的類。
  • 裝飾角色:持有一個構建對象的實例,並定義一個與抽象構建接口一致的接口。
  • 具體裝飾角色:負責給構建對象貼上附加的責任。

具體裝飾角色實現了構建接口,對於每個實現的方法都委派給父類的構建角色,關鍵在於它功能的加強,而不是單純地委派。spa

  • 示例:IO設計

java api的io類庫中對於適配器裝飾器的應用隨處可見,這裏以讀取文件爲例,看一下其中的相關的幾個類。設計

// 讀取一個文件內容
BufferedReader in = new BufferedReader(new FileReader(new File("test.txt")));

BufferedReader是一個典型的裝飾器模式,它實現了Reader接口,同時也擁有Reader子類的一個實例,這裏也就是FileReader,而後將全部的讀取任務都委託給了FileReader的實例,可是增長了緩存讀取功能。code

咱們一般會說InputStreamReader是從byte輸入流到char輸入流的一個適配器,但其實起到適配器做用的是StreamDecoder,它擁有InputStream的實例同時實現了Reader接口,而InputStreamReader在此基礎上進一步裝飾了StreamDecoder。對象

說一個讓java初學者糾結的一個問題,io流關閉問題:因爲使用的裝飾器模式,對於io流的close,咱們只要調用最外層的close方法就能夠了。好比BufferedReader會將close的操做委託給reader實例,這個實例正常是InputStreamReader的實現,而後InputStreamReader又委託給StreamDecoder,最後StreamDecoder又會委託給InputStream的實現類,最終實現了IO流關閉,反過來若是提早調用了委託類的close方法,那麼上層的讀取也會失敗。

blog

#筆記內容參考《java與模式》

相關文章
相關標籤/搜索