1.適配器模式概念
作為兩個不兼容的接口之間的橋梁,它屬于結(jié)構(gòu)型模式。
2.適配器模式作用
適配器模式(Adapter Pattern),將一個類的接口轉(zhuǎn)換成客戶期望的另一個接口。適配器讓原本不兼容的類可以合作無間(《Head First Design Patterns》上解釋道)。
3.何時使用
1、系統(tǒng)需要使用現(xiàn)有的類,而此類的接口不符合系統(tǒng)的需要。
2、想要建立一個可以重復(fù)使用的類,用于與一些彼此之間沒有太大關(guān)聯(lián)的一些類,包括一些可能在將來引進的類一起工作,這些源類不一定有一致的接口。
3、通過接口轉(zhuǎn)換,將一個類插入另一個類系中。(比如老虎和飛禽,現(xiàn)在多了一個飛虎,在不增加實體的需求下,增加一個適配器,在里面包容一個虎對象,實現(xiàn)飛的接口。)
4.優(yōu)點和缺點
優(yōu)點
1、可以讓任何兩個沒有關(guān)聯(lián)的類一起運行。
2、提高了類的復(fù)用。
3、增加了類的透明度。
4、靈活性好。
缺點
1、過多地使用適配器,會讓系統(tǒng)非常零亂,不易整體進行把握。比如,明明看到調(diào)用的是 A 接口,其實內(nèi)部被適配成了 B 接口的實現(xiàn),一個系統(tǒng)如果太多出現(xiàn)這種情況,無異于一場災(zāi)難。因此如果不是很有必要,可以不使用適配器,而是直接對系統(tǒng)進行重構(gòu)。
2.由于 JAVA 至多繼承一個類,所以至多只能適配一個適配者類,而且目標(biāo)類必須是抽象類。
5.適配器解析
適配器分為兩種,一種是對象適配器,一種是類適配器。對象適配器是使用組合實現(xiàn)的,而類適配器是使用繼承實現(xiàn)的,并且類適配器模式在JAVA中實現(xiàn)不了,因為它使用了多重繼承,需要使用支持多重繼承的語言才能實現(xiàn),如C++。
對象適配器類圖:

類適配器類圖:

下面是類適配器源碼解析:這是通過適配器將火雞變成鴨子的例子
Target接口:即通過適配器將被適配者轉(zhuǎn)換成Target
public interface Duck {
public void quack();
public void fly();
}
Adapter:適配器
public class TrukeyAdapter implements Duck {
Turkey turkey = null;
public TrukeyAdapter(Turkey turkey) {
this.turkey = turkey;
}
@Override
public void fly() {
for (int i = 0; i < 5; i++) {
turkey.fly();
}
}
@Override
public void quack() {
turkey.gobble();
}
}
Adaptee:被適配者
被適配者接口:
public interface Turkey {
public void gobble();
public void fly();
}
被適配者具體實例:
public class WildTurkey implements Turkey {
@Override
public void fly() {
System.out.println("I'm flying a short distance");
}
@Override
public void gobble() {
System.out.println("Gobble gobble");
}
}
客戶端:
/**
* @author Administrator
* Adapter---TrukeyAdapter
* Adaptee---Turkey
* Target---Duck
*
*/
public class DuckTestDrive {
public static void main(String[] args) {
MarllarDuck marllarDuck = new MarllarDuck();
WildTurkey wildTurkey = new WildTurkey();
Duck turkeyAdapter = new TrukeyAdapter(wildTurkey);
System.out.println("The Turkey say......");
wildTurkey.gobble();
wildTurkey.fly();
System.out.println("\nThe Duck say......");
testDuck(marllarDuck);
System.out.println("\nThe TrukeyAdapter say......");
testDuck(turkeyAdapter);
}
private static void testDuck(Duck duck) {
duck.quack();
duck.fly();
}
}
這個例子是《Head First Design Patterns》里面的,也許不太明白將火雞變成鴨子這個例子,那么來說一個比較容易理解的例子,中國電器的插頭和美國電器插頭不一樣,所以中國電器是無法插入美國的插排的,所以需要一個適配器,能讓中國電器的插頭能插上美國的插排。這里中國電器的插頭就像是火雞(被適配者),而美國的插頭就是鴨子(Target),我們要通過適配器將中國插頭變成美國插頭,這樣中國電器才能在美國使用。
6.總結(jié)
Client使用Adapter的過程:
1.Client通過Target接口調(diào)用Adapter的方法,對適配器發(fā)出請求。
//Duck就是Target
private static void testDuck(Duck duck) {
duck.quack();
duck.fly();
}
2.Adapter使用Adaptee接口把請求轉(zhuǎn)換成Adaptee的一個或多個調(diào)用接口。
//在適配器TrukeyAdapter中的quack()方法中,調(diào)調(diào)用了Adaptee(也就是Turkey的gobble()方法)
@Override
public void quack() {
turkey.gobble();
}
3.Client接收到調(diào)用結(jié)果,但并未察覺這一切是Adapter在啟轉(zhuǎn)換作用。
7.源碼地址
http://download.csdn.net/detail/lgywsdy/9749997