Linux 使用命令傳送郵件
設計模式之簡單討論
介面卡模式
將一個類的介面轉換成客戶想要的另一個介面,介面卡模式使得原本由於介面不相容而不能一起工作的那些類可以一起工作
舉個例子,就像轉換器或者轉接頭一樣。你的電源插座只有兩相插座,但是你的筆記本需要三相插座,那怎麼辦?你會去找一個三相轉兩相的轉接器。所以,介面卡的功能就是做兩頭的轉換。
1:重要角色
目標:目標是一個介面,該介面是客戶想使用的介面
被適配者:被適配者可以是一個已存在的介面或抽象類或普通類,這個介面或抽象類或普通類需要適配
介面卡:介面卡是一個類,該類實現了目標介面
2:實現方式
1.類的介面卡模式(採用繼承實現)
2.物件介面卡(採用物件組合方式實現)
3.介面介面卡(採用抽象類方式實現)
2.1類介面卡
我們生活中常常聽到的是電源介面卡,它是用於電流變換(整流)的裝置。介面卡的存在,就是為了將已存在的東西(介面)轉換成適合我們的需要、能被我們所利用。在現實生活中,介面卡更多的是作為一箇中間層來實現這種轉換作用。
其中:
• Target
— 定義Client使用的與特定領域相關的介面。
• Client
— 與符合Target介面的物件協同。
• Adaptee
— 定義一個已經存在的介面,這個介面需要適配。
• Adapter
— 對Adaptee的介面與Target介面進行適配
在上面的通用類圖中,Cient 類最終面對的是 Target 介面(或抽象類),它只能夠使用符合這一目標標準的子類;而 Adaptee 類則是被適配的物件(也稱 源角色),因為它包含specific (特殊的)操作、功能等,所以我們想要在自己的系統中使用它,將其轉換成符合我們標準的類,使得 Client 類可以在透明的情況下任意選擇使用 ConcreteTarget 類或是具有特殊功能的 Adatee 類。
程式碼示例 // 目標介面,或稱為標準介面 interface Target { public void request(); } // 具體目標類,只提供普通功能class ConcreteTarget implements Target { public void request() { System.out.println("普通類 具有 普通功能..."); } } // 已存在的、具有特殊功能、但不符合我們既有的標準介面的類 class Adaptee { public void specificRequest() { 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 類中我們可以根據需要選擇並建立任一種符合需求的子類,來實現具體功能。
2.2 物件介面卡
物件介面卡它不是使用多繼承或繼承再實現的方式,而是使用直接關聯,或者稱為委託的方式,類圖如下
程式碼示例 // 目標介面,或稱為標準介面 interface Target { public void request(); } // 具體目標類,只提供普通功能 class ConcreteTarget implements Target { public void request() { System.out.println("普通類 具有 普通功能..."); } } // 已存在的、具有特殊功能、但不符合我們既有的標準介面的類 class Adaptee { public void specificRequest() { System.out.println("被適配類具有 特殊功能..."); } } // 介面卡類,直接關聯被適配類,同時實現標準介面 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(); } }
思考:
物件模式下介面卡類持有的被適配物件如何設計?
請參見最後的適用場景
2.3 介面介面卡
思考:
當存在這樣一個介面,其中定義了很多很多方法,而我們現在卻只想使用其中的一個到幾個方法如何處理?
程式碼實現 public class AdapterDemo { public static void main(String[] args) { A a = new AdapterTest(); a.a(); a.d(); } } interface A { void a(); void b(); void c(); void d(); void e(); void f(); } abstract class Adapter implements A { public void a() {} public void b() {} public void c() {} public void d() {} public void e() {} public void f() {} } class AdapterTest extends Adapter { //只需要重寫自己需要的方法 public void a() { System.out.println("實現A方法被呼叫"); } public void d() { System.out.println("實現d方法被呼叫"); } }
通過如上示例可以看出:介面介面卡是以抽象類作為適配 和前兩種有著根本區別
3:適用場景
1:你想使用一個已經存在的類,而它的介面不符合你的需求。
2:你想建立一個可以複用的類,該類可以與其他不相關的類或不可預見的類(即那些介面可能不一定相容的類)協同工作。
3:你想使用一些已經存在的子類,但是不可能對每一個都進行子類化匹配它們的介面。物件介面卡可以適配它的父類介面----面向物件多型的使用所以物件介面卡比較靈活
優缺點:
優點:
更好的複用性和擴充套件性
缺點:
很多的介面卡結合起來,會使系統過於過亂,不容易把握。
總結:介面卡模式相對簡單,精髓就是兩個字“相容”。