標籤:blog http java 使用 io 2014 art ar
Adapter Pattern的作用是在不改變功能的前提下轉換介面。Adapter分為兩類,一類是Object Adapter, 還有一類是Class Adapter。因為Class Adapter的實現須要用到多繼承,而Java不支援多繼承,所以這裡僅僅關注Object Adapter。
在JDK1.5之前是沒有 java.util.Iterator 介面的,java.util.Enumeration 介面起著 Iterator 的作用。那麼假設我們須要維護一些年代比較久遠的代碼,可能就會面臨著沒有 Iterator 的窘境。這時候 Adapter Pattern 就派上用場了。以下通過兩個範例,說明怎樣通過 Adapter Pattern 將 Enumeration 介面與 Iterator 介面相互“轉換”。
老代碼適配新代碼:將Enumeration轉換為Iterator查了一下API文檔,發現 StringTokenizer 這個類實現了 Enumeration 介面,那就拿這個來舉例吧。如今有需求,須要用 Iterator 的方式來"遍曆" StringTokenizer,可是 StringTokenizer類並沒有實現 Iterator 介面。因此我們須要編寫一個 Adapter,將 Enumeration 介面轉換成 Iterator 介面。
class IteratorAdapter implements Iterator {private Enumeration enume; // 儲存 Enumeration 介面實作類別public IteratorAdapter(Enumeration enume) {this.enume = enume;}/** * Enumeartion的hasMoreElements()方法與Iterator的hasNext()方法功能同樣,直接調用 */@Overridepublic boolean hasNext() {return enume.hasMoreElements();}/** * Enumeration的next()方法與Iterator的next()方法功能同樣,直接調用 */@Overridepublic Object next() {return enume.nextElement();}/** * 因為Enumeration介面中沒有此方法,所以扔異常 */@Overridepublic void remove() {throw new UnsupportedOperationException();}}
能夠看到,我們實際上僅僅是把沒有實現的 Iterator 介面裡的方法實現託付給了 Enumeration 介面的實現。Adapter 的用法例如以下:
StringTokenizer st = new StringTokenizer("a b c d e f g");// 建立adapter對象,將StringTokenizer對象傳進去IteratorAdapter strTokenAdapter = new IteratorAdapter(st);// 這時候就能夠用Iterator的方式遍曆沒有實現Iterator介面的對象了while(strTokenAdapter.hasNext()) {out.println(strTokenAdapter.next());}
新代碼適應老代碼:將Iterator轉換為Enumeration反過來的過程就非常easy的了,由於 Enumeration 介面裡的方法在 Iterator 中都有定義。
class EnumerationAdapter implements Enumeration {private Iterator it;public EnumerationAdapter(Iterator it) {this.it = it;}@Overridepublic boolean hasMoreElements() {return it.hasNext();}@Overridepublic Object nextElement() {return it.next();}}
像上面 IteratorAdapter 和 EnumerationAdapter 那樣把要被適配的對象儲存到類的成員變數裡的方式,就叫 Object Adapter。而還有一種 Class Adapter則是要求 Adapter 類同一時候繼承適配的兩方。比方,有一個名為Apple的類和名為Banana的類,它們的public方法不同樣。如今想以調用Apple類方法的方式使用Banana類,那麼對於 Class Adapter 來說,就應該讓 Adapter 同一時候繼承 Apple 和 Banana,然後通過 Adapter 完畢方法調用。有興趣的話能夠用C++實現一下試試。