以前已經將五個建立型設計模式介紹完了,從這一篇開始介紹結構型設計模式,適配器模式就是結構型模式的一種,適配器要實現的效果是把「源」過渡到「目標」。html
在開發過程當中,使用一個已經存在的類,而他的接口不符合咱們的需求。這個時候咱們本着開閉原則,要建立一個既符合咱們需求又實現了已存在的接口的類,這個類能夠把其餘不相關或不可預見的類協同起來一塊兒工做。咱們建立的這個類就是適配器類,起到了一個轉換的做用。設計模式
適配器模式有類型的適配器模式和對象適配器模式兩種實現方式。app
面向類的適配器實現起來並不複雜,主要的思想就是靠繼承來實現適配。舉個🌰,若是咱們在調用一個接口的時候,發現這個接口中沒有能實現咱們需求的方法,而後發現這個接口旁邊的一個類中有咱們想要的方法,這個時候咱們就能夠建立一個適配器類,來繼承接口旁邊的這個類,並實現調用接口。這樣就知足了咱們既沒有改變調用方式又實現了功能需求。ide
以下代碼功能:函數
定義一個數據線接口post
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:數據線"; } }
使用方式以下:this
public class AdapterTest { public static void main(String[] args) { HuaWei dataLine = new Adapter(); String typC = dataLine.huawei();
System.out.println(typC); } }
運行結果:google
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設計模式概述。