java設計模式之介面卡模式
介面卡模式的定義:
介面卡模式又叫作變壓器模式,它的功能是將一個類的介面變成客戶端所期望的另一個介面,從而使原本因介面不匹配而導致
無法在一起工作的兩個類能夠一起工作,屬於結構型設計模式。
在軟體開發過程中,基本上任何問題都可以通過增加一箇中間層來解決。介面卡模式其實就是一箇中間層。介面卡模式起著轉化
/委託的作用,將一種介面轉化為另一種符合需要的介面。
介面卡模式的應用場景:
- 已經存在的類,它的方法和需求不匹配(方法結果相同或相似)的情況。
- 介面卡模式不是軟體設計階段考慮的設計模式,是隨著軟體維護,由於不同產品不同廠家造成功能類似而介面不相同情況下的解決方案,有種亡羊補牢的感覺。
介面卡模式有三種形式:類介面卡、物件介面卡、介面介面卡。介面卡模式一般包含三個角色:
- 目標角色(ITarget):也就是我們期望的介面。
- 源角色(Adaptee):存在於系統中,內容滿足客戶需求但介面不匹配的介面例項。
- 介面卡(Adapter):將Adaptee轉化為目標角色ITarget的類例項。
類介面卡的UML類圖以及通用寫法:
類介面卡的原理就是通過繼承來實現介面卡功能。具體做法就是Adapter繼承Adaptee並實現ITarget介面,這樣Adapter就具備了Adaptee和ITarget的特性,可以將
兩者進行轉化,其UML類圖如下:
我們用一個例子來進行講解。在中國,民用電都是220V交流電,但用手機使用的鋰電池使用的是5V的直流電。因此,當手機充電時,需要使用電源介面卡來進行轉換,
我們用程式碼來還原這個場景,首先建立Adaptee角色類,需要被轉換的物件AC220,表示220V交流電。
public class AC220 { public int outputAC220V(){ int output = 220; System.out.println("輸出電壓" + output + "V"); return output; } }
建立ITarget角色DC5介面,表示5V直流電。
public interface DC5 { int output5V(); }
建立Adapter角色的電源介面卡PowerAdapter類。
public class PowerAdapter extends AC220 implements DC5 { public int output5V() { int adapterInput = super.outputAC220V(); int adapterOutput = adapterInput / 44; System.out.println("使用Adapter輸入AC" + adapterInput + "V,輸出DC" + adapterOutput + "V"); return adapterOutput; } }
測試程式碼。
public class Test { public static void main(String[] args) { DC5 adapter = new PowerAdapter(); adapter.output5V(); } }
物件介面卡的UML類圖及通用寫法:
物件介面卡的原理就是通過組合來實現介面卡的功能。具體做法是,首先讓Adapter實現ITarget介面,然後內部持有Adaptee例項。這樣做使得程式碼更加靈活,比如
我們需要將兩個不同的源角色(Adaptee)整合成一個ITarget目標角色,顯然這個時候用繼承就沒辦法實現了,所以這也是為什麼我們要多用組合少用繼承的原因。其UML
類圖如下:
接前面的示例,程式碼只需要更改Adapter實現,及去掉繼承Adaptee類,並將Adaptee作為內部屬性注入,其他與類介面卡一致。
public class PowerAdapter implements DC5 { private AC220 ac220; public PowerAdapter(AC220 ac220) { this.ac220 = ac220; } public int output5V() { int adapterInput = ac220.outputAC220V(); int adapterOutput = adapterInput / 44; System.out.println("使用Adapter輸入AC" + adapterInput + "V,輸出DC" + adapterOutput + "V"); return adapterOutput; } }
介面介面卡的UML類圖及通用寫法:
介面介面卡的關注點和前面兩個介面卡不太一樣,當我們的源角色和目標角色的介面能夠匹配的情況下,但是我們的目標角色可能包含多個源角色的功能,
也就是有其他的除了源角色對應抽象方法以外的抽象方法,這樣如果我們目標角色之間實現源角色介面的話,會多出許多空的實現方法,顯得臃腫。此時就需要
使用介面介面卡來實現了,介面介面卡的UML類圖以及寫法都和物件介面卡的完全一樣,唯一的區別是,在目標角色介面中多了幾個抽象方法,然後在介面卡角
色中多了抽象方法對應的源角色屬性注入。所以這裡就不再列舉了。
介面卡模式的優點:
- 能提高類的透明性和複用,但現有的類不需要改變。
- 介面卡類和原角色類解耦,提高程式的擴充套件性。
- 在很多業務場景中符合開閉原則。
介面卡模式的缺點:
- 介面卡編寫過程需要結合業務場景全面考慮,可能會增加系統的複雜性。
- 增加程式碼閱讀難度,降低程式碼可讀性,過多使用介面卡會使系統程式碼變得凌亂。