1.生活中的問題
歐洲使用的插座是圓孔的,而我國使用的是扁形的插頭,如何能讓國標的插頭能在歐標的插座上使用呢吆倦?答案是我們可以買一個歐標插頭適配器(也稱插頭轉(zhuǎn)接器)说订。有了這個抄瓦,國標的插頭就可以使用歐標插座供電了。
在面向開發(fā)過程當中陶冷,有時候也會存在這種不兼容的情況钙姊,我們可以引入一個像是交流電適配器的我們叫他“適配器”的角色,來協(xié)調(diào)者兩種不兼容的情況埂伦。這種設(shè)計方案就叫做適配器模式煞额。
2.模式介紹
2.1.模式定義
適配器模式:即定義一個包裝類,用于包裝不兼容接口的對象
包裝類 = 適配器(Adapter)
被包裝對象 = 適配者(Adaptee)
2.2模式作用
把一個類的接口變成客戶端能用的另一種接口木西,使原本不兼容的兩個類能一起工作
2.3.模式組成
適配器模式有以下幾個角色組成:
1. Target:目標抽象類/接口
2. Adapter:適配器類
3. Adaptee:適配者類
4. Client:客戶類
3.模式原理和實例講解
3.1.類適配器
3.1.1 UML類圖 & 組成
在類適配器中称簿,適配器Adapter繼承適配者類Adaptee和Target接口凸克,實現(xiàn)目標抽象接口Target的Request() 方法。并且在方法里面調(diào)用父類的 Specific Request()方法婚温,從而實現(xiàn)了適配。
3.1.2 使用步驟
1. 創(chuàng)建目標抽象類 /接口 (Target)
2. 創(chuàng)建適配者類 (Adaptee)
3. 創(chuàng)建適配器類 (Adapter)
4. 創(chuàng)建客戶類 (Client)
3.1.3 實例講解
目標抽象接口 IGBPlug:
public Interface IGBPlug {
//使用國標插頭充電
public void GBPlugCharge();
}
適配者類 OBSocket:
public class OBSocket {
public void OBSocketCharge(){
System.out.println(“使用歐標插座充電");
}
}
適配器類:
public class PlugAdapter extends OBSocket implements IGBPlug{
@Override
public void GBPlugCharge() {
OBSocketCharge();
}
}
客戶類:
public class NoteBook {
private IGBPlug ipl;
public NoteBook(IGBPlug ipl){ this. ipl = ipl;}
public void charge(){
ipl.GBPlugCharge();
}
}
測試類:
public class Test {
public static void mian(String[] args){
IGBPlug ipl = new PlugAdapter();
NoteBook nb = new NoteBook(ipl);
nb.charge();
}
}
3.1.4 運行結(jié)果:
3.1.5 類適配器優(yōu)缺點
優(yōu)點:
由于適配器類是適配者類的子類涩僻,因此可以在適配器類中置換一些適配者的方法缭召,使得適配器的靈活性更強
缺點:
適配者類不能為最終類
因為java不支持多繼承,目標抽象類只能為接口
一次最多只能適配一個適配者類逆日,不能同時適配多個適配者
那問題來了嵌巷,我們有很多個適配者類的話,那就要創(chuàng)建很多個適配器室抽,是不是很麻煩呢搪哪?那有沒有更好的解決辦法?有坪圾,就是接下來我要講的對象適配器
3.2.對象適配器
3.2.1 UML類圖
對象適配器和類適配器的區(qū)別是晓折,它不需要繼承適配者類。它可以把多個適配者類作為對象包含在適配器里面兽泄,通過適配者的對象調(diào)用響應(yīng)的方法漓概,省去了創(chuàng)建適配器的麻煩。
對象適配器 PlugAdapterObj:
public class PlugAdapterObj implements IGBPlug {
//把OBSocket作為對象組合到適配器里面
private OBSocket obSocket;
public PlugAdapterObj(OBSocket obSocket){this.obSocket = obSocket;}
@Override
public void GBPlugCharge() {
System.out.println("通過對象適配器");
obSocket.OBSocketCharge();
}
}
修改Test類:
public class Test {
public static void main(String[] args) {
//需要創(chuàng)建一個適配者類作為對象
OBSocket obSocket = new OBSocket();
IGBPlug ipl = new PlugAdapterObj(obSocket);
NoteBook nb = new NoteBook(ipl);
nb.charge();
}
}
3.2.2 運行結(jié)果:
3.2.3 對象適配器優(yōu)缺點
優(yōu)點:
把多個不同的適配者適配到同一個目標接口病梢,省去了創(chuàng)建適配器的麻煩胃珍。具有靈活性
缺點:
與類適配器模式相比梁肿,要想置換適配者類的方法就不容易,比較復雜
4.適配器總結(jié)
1.更好的復用性
系統(tǒng)需要使用現(xiàn)有的類觅彰,而此類的接口不符合系統(tǒng)的需要吩蔑。那么通過適配器模式就可以讓這些功能得到更好的復用。
2.透明填抬、簡單
客戶端可以調(diào)用同一接口烛芬,所以對客戶端來說是透明的。這樣做更簡單&更直接
3.更好的擴展性
在實現(xiàn)適配器功能的時候飒责,可以調(diào)用自己開發(fā)的功能赘娄,從而自然地擴展系統(tǒng)的功能。
4.解耦性
將目標類和適配者類解耦读拆,通過引入一個適配器類重用現(xiàn)有的適配者類擅憔,而無需修改原有代碼
5.符合開閉原則
同一個適配器可以把適配者類和它的子類都適配到目標接口;可以為不同的目標接口實現(xiàn)不同的適配器檐晕,而不需要修改待適配類
5.應(yīng)用場景
系統(tǒng)需要使用一些現(xiàn)有的類暑诸,而這些類的接口不符合系統(tǒng)的需要,甚至沒有這些類的源代碼辟灰。
想創(chuàng)建一個可以重復使用的類个榕,用于與一些彼此之間沒有太大關(guān)聯(lián)的一些類,包括一些可能在將來引進的類一起工作