前言
之前已經將五個創建型設計模式介紹完了,從這一篇開始介紹結構型設計模式,適配器模式就是結構型模式的一種,適配器要實現的效果是把“源”過渡到“目標”。
適配器模式
在開發過程中,使用一個已經存在的類,而他的接口不符合我們的需求。這個時候我們本着開閉原則,要創建一個既符合我們需求又實現了已存在的接口的類,這個類可以把其他不相關或不可預見的類協同起來一起工作。我們創建的這個類就是適配器類,起到了一個轉換的作用。
適配器模式有類型的適配器模式和對象適配器模式兩種實現方式。
面向類的適配器模式
面向類的適配器實現起來並不復雜,主要的思想就是靠繼承來實現適配。舉個🌰,如果我們在調用一個接口的時候,發現這個接口中沒有能實現我們需求的方法,然后發現這個接口旁邊的一個類中有我們想要的方法,這個時候我們就可以創建一個適配器類,來繼承接口旁邊的這個類,並實現調用接口。這樣就滿足了我們既沒有改變調用方式又實現了功能需求。
如下代碼功能:
定義一個數據線接口
public interface IMobilePhone { /** * 谷歌數據線 * @return */ String google(); /** * 蘋果數據線 * @return */ String apple(); }
當我們調用數據線接口時發現沒有type-c類型接口的數據線,然后發現了下面的這個類里有。
public class HuaWei { /** * 華為的type-c數據線 * @return */ public String huawei(){ return "huawei:type-C"; } }
然后我們就創建一個適配器類來滿足我們的需求。
public class Adapter extends HuaWei implements IMobilePhone { @Override public String google() { return "Android:數據線"; } @Override public String apple() { return "IOS:數據線"; } }
使用方式如下:
public class AdapterTest { public static void main(String[] args) { HuaWei dataLine = new Adapter(); String typC = dataLine.huawei();
System.out.println(typC); } }
運行結果:
huawei:type-C
在上面的例子中,我們通過Adapter類繼承自HuaWei類,然后實現了IMobilePhone接口,做到了適配的效果,但是這種適配器是有明確規定了父類的。由於Java語言的特性,類只能單繼承,決定了這個適配器只能用在這個業務當中。如果我們又需要另一個類里面的方法呢?這個時候就又需要創建一個子類來實現適配,這也是為什么這種方式叫類適配器的原因。
面向對象適配器模式
為了解決類適配器只是適配單一類的這個問題,就又出現了對象適配器模式,對象適配器,是將適合類的對象注入到適配器中,然后達到適配的作用。
其他的代碼沒有變化,只需要更改適配器類。
更改后如下所示:
public class Adapter implements IMobilePhone { @Override public String google() { return "Android:數據線"; } @Override public String apple() { return "IOS:數據線"; } public Adapter(){} private HuaWei huaWei; public Adapter(HuaWei huaWei){ this.huaWei = huaWei; } public String huawei(){ return huaWei.huawei(); } }
適配器類,不再繼承HuaWei類,而是通過構造函數將HuaWei類的對象注入進來,然后定義一個方法來調用要使用的方法。
測試如下:
public class AdapterTest { public static void main(String[] args) { HuaWei huaWei = new HuaWei(); Adapter dataLine = new Adapter(huaWei); String typC = dataLine.huawei(); System.out.println(typC); } }
運行結果:
huawei:type-C
對象適配器模式,可以為多個類進行適配(多個構造方法),解決了類適配模式的單一化問題。
但是其實除了對象適配器模式和類適配器模式,還有一種方式也是實現適配的方法,接口適配器模式。當我們想實現一個接口,但又不想實現所有接口方法,而只想去實現一部分方法時,就可以使用接口適配器。它的做法是在接口和具體實現類中添加一個抽象類,而用這個抽象類去實現目標接口的所有方法。而具體的實現類只需要覆蓋其需要完成的方法即可。
例如有如下接口:
public interface MobilePhoneBrand { String xiaomi(); String huawei(); String apple(); String vivo(); String oppo(); String samsung(); }
對應的抽象類如下:
public abstract class MobilePhoneDefault implements MobilePhoneBrand{ public String xiaomi(){ return null; } public String huawei(){ return null; } public String apple(){ return null; } public String vivo(){ return null; } public String oppo(){ return null; } public String samsung(){ return null; } }
實現類中我只想使用中國品牌的手機,所以只需實現部分方法就可以了。
public class ChinaMobilePhone extends MobilePhoneDefault { public String xiaomi(){ return "小米"; } public String huawei(){ return "華為"; } public String vivo(){ return "VIVO"; } public String oppo(){ return "OPPO"; } }
適配器模式的3個實現方式介紹完了,下面來說說適配器模式的結構,如下圖:

適配器模式中有如下4個角色:
目標抽象角色(Target):定義客戶所期待要使用的接口,在第一個例子中的IMobilePhone就是代表的這個角色。
源角色(Adaptee):也叫被適配角色,在第一例子中HuaWei代表的就是這個角色。
適配器角色(Adapter):用來把源角色轉換成符合要求的目標接口設備,在第一個例子中Adapter類代表的就是這個角色。
客戶端(Client):這個就是具體使用角色,在第一個例子中的AdapterTest代表的就是這個角色。
想了解更多的設計模式請查看Java設計模式學習記錄-GoF設計模式概述。
