JAVA設計模式初探之介面卡模式
1. 概述
將一個類的介面轉換成客戶希望的另外一個介面。Adapter模式使得原本由於介面不相容而不能一起工作的那些類可以在一起工作。
2. 解決的問題
即Adapter模式使得原本由於介面不相容而不能一起工作的那些類可以在一起工作。
下面是兩個非常形象的例子
3. 模式中的角色
3.1 目標介面(Target):客戶所期待的介面。目標可以是具體的或抽象的類,也可以是介面。
3.2 需要適配的類(Adaptee):需要適配的類或適配者類。
3.3 介面卡(Adapter):通過包裝一個需要適配的物件,把原介面轉換成目標介面。
4. 實現方式
(1)類的介面卡模式(採用繼承實現)
(2)物件介面卡(採用物件組合方式實現)
介面卡模式的類圖
一。類的介面卡模式
// 已存在的、具有特殊功能、但不符合我們既有的標準介面的類 class Adaptee { public void specificRequest() { System.out.println("被適配類具有 特殊功能..."); } } // 目標介面,或稱為標準介面 interface Target { public void request(); } // 具體目標類,只提供普通功能 class ConcreteTarget implements Target { public void request() { System.out.println("普通類 具有 普通功能..."); } } // 介面卡類,繼承了被適配類,同時實現標準介面 class Adapter extends Adaptee implements Target{ public void request() { super.specificRequest(); } } // 測試類public class Client { public static void main(String[] args) { // 使用普通功能類 Target concreteTarget = new ConcreteTarget(); concreteTarget.request(); // 使用特殊功能類,即適配類 Target adapter = new Adapter(); adapter.request(); } }
測試結果:
普通類 具有 普通功能...
被適配類具有 特殊功能...
上面這種實現的介面卡稱為類介面卡,因為 Adapter 類既繼承了 Adaptee (被適配類),也實現了 Target 介面(因為 Java 不支援多繼承,所以這樣來實現),在 Client 類中我們可以根據需要選擇並建立任一種符合需求的子類,來實現具體功能。另外一種介面卡模式是物件介面卡,它不是使用多繼承或繼承再實現的方式,而是使用直接關聯,或者稱為委託的方式,類圖如下:
程式碼如下:
// 介面卡類,直接關聯被適配類,同時實現標準介面 class Adapter implements Target{ // 直接關聯被適配類 private Adaptee adaptee; // 可以通過建構函式傳入具體需要適配的被適配類物件 public Adapter (Adaptee adaptee) { this.adaptee = adaptee; } public void request() { // 這裡是使用委託的方式完成特殊功能 this.adaptee.specificRequest(); } } // 測試類 public class Client { public static void main(String[] args) { // 使用普通功能類 Target concreteTarget = new ConcreteTarget(); concreteTarget.request(); // 使用特殊功能類,即適配類, // 需要先建立一個被適配類的物件作為引數 Target adapter = new Adapter(new Adaptee()); adapter.request(); } }
測試結果與上面的一致。從類圖中我們也知道需要修改的只不過就是 Adapter 類的內部結構,即 Adapter 自身必須先擁有一個被適配類的物件,再把具體的特殊功能委託給這個物件來實現。使用物件介面卡模式,可以使得 Adapter 類(適配類)根據傳入的 Adaptee 物件達到適配多個不同被適配類的功能,當然,此時我們可以為多個被適配類提取出一個介面或抽象類。這樣看起來的話,似乎物件介面卡模式更加靈活一點。
5. 模式總結
5.1 優點
5.1.1 通過介面卡,客戶端可以呼叫同一介面,因而對客戶端來說是透明的。這樣做更簡單、更直接、更緊湊。
5.1.2 複用了現存的類,解決了現存類和複用環境要求不一致的問題。
5.1.3 將目標類和適配者類解耦,通過引入一個介面卡類重用現有的適配者類,而無需修改原有程式碼。
5.1.4 一個物件介面卡可以把多個不同的適配者類適配到同一個目標,也就是說,同一個介面卡可以把適配者類和它的子類都適配到目標介面。
5.2 缺點
對於物件介面卡來說,更換介面卡的實現過程比較複雜。
5.3 適用場景
5.3.1 系統需要使用現有的類,而這些類的介面不符合系統的介面。
5.3.2 想要建立一個可以重用的類,用於與一些彼此之間沒有太大關聯的一些類,包括一些可能在將來引進的類一起工作。
5.3.3 兩個類所做的事情相同或相似,但是具有不同介面的時候。
5.3.4 舊的系統開發的類已經實現了一些功能,但是客戶端卻只能以另外介面的形式訪問,但我們不希望手動更改原有類的時候。
5.3.5 使用第三方元件,元件介面定義和自己定義的不同,不希望修改自己的介面,但是要使用第三方元件介面的功能。
6. 介面卡應用舉例
6.1 使用過ADO.NET的開發人員應該都用過DataAdapter,它就是用作DataSet和資料來源之間的介面卡。DataAdapter通過對映Fill和Update來提供這一介面卡。
6.2 手機電源介面卡
作者:jason0539