適配器模式(Adapter)
適配器模式將某個(gè)類(lèi)的接口轉(zhuǎn)換成客戶端期望的另一個(gè)接口表示,目的是消除由于接口不匹配所造成的類(lèi)的兼容性問(wèn)題。主要分為三類(lèi):類(lèi)的適配器模式、對(duì)象的適配器模式、接口的適配器模式。首先,我們來(lái)看看類(lèi)的適配器模式,先看類(lèi)圖:
核心思想就是:有一個(gè)Source類(lèi),擁有一個(gè)方法,待適配,目標(biāo)接口時(shí)Targetable,通過(guò)Adapter類(lèi),將Source的功能擴(kuò)展到Targetable里,看代碼:
[java] view plain copy
public class Source {
public void method1() {
System.out.println("this is original method!");
}
}
[java] view plain copy
public interface Targetable {
/* 與原類(lèi)中的方法相同 */
public void method1();
/* 新類(lèi)的方法 */
public void method2();
}
[java] view plain copy
public class Adapter extends Source implements Targetable {
@Override
public void method2() {
System.out.println("this is the targetable method!");
}
}
Adapter類(lèi)繼承Source類(lèi),實(shí)現(xiàn)Targetable接口,下面是測(cè)試類(lèi):
[java] view plain copy
public class AdapterTest {
public static void main(String[] args) {
Targetable target = new Adapter();
target.method1();
target.method2();
}
}
輸出:
this is original method!
this is the targetable method!
這樣Targetable接口的實(shí)現(xiàn)類(lèi)就具有了Source類(lèi)的功能。
對(duì)象的適配器模式
基本思路和類(lèi)的適配器模式相同,只是將Adapter類(lèi)作修改,這次不繼承Source類(lèi),而是持有Source類(lèi)的實(shí)例,以達(dá)到解決兼容性的問(wèn)題??磮D:
只需要修改Adapter類(lèi)的源碼即可:
[java] view plain copy
public class Wrapper implements Targetable {
private Source source;
public Wrapper(Source source){
super();
this.source = source;
}
@Override
public void method2() {
System.out.println("this is the targetable method!");
}
@Override
public void method1() {
source.method1();
}
}
測(cè)試類(lèi):
[java] view plain copy
public class AdapterTest {
public static void main(String[] args) {
Source source = new Source();
Targetable target = new Wrapper(source);
target.method1();
target.method2();
}
}
輸出與第一種一樣,只是適配的方法不同而已。
第三種適配器模式是接口的適配器模式,接口的適配器是這樣的:有時(shí)我們寫(xiě)的一個(gè)接口中有多個(gè)抽象方法,當(dāng)我們寫(xiě)該接口的實(shí)現(xiàn)類(lèi)時(shí),必須實(shí)現(xiàn)該接口的所有方法,這明顯有時(shí)比較浪費(fèi),因?yàn)椴⒉皇撬械姆椒ǘ际俏覀冃枰?,有時(shí)只需要某一些,此處為了解決這個(gè)問(wèn)題,我們引入了接口的適配器模式,借助于一個(gè)抽象類(lèi),該抽象類(lèi)實(shí)現(xiàn)了該接口,實(shí)現(xiàn)了所有的方法,而我們不和原始的接口打交道,只和該抽象類(lèi)取得聯(lián)系,所以我們寫(xiě)一個(gè)類(lèi),繼承該抽象類(lèi),重寫(xiě)我們需要的方法就行??匆幌骂?lèi)圖:
這個(gè)很好理解,在實(shí)際開(kāi)發(fā)中,我們也常會(huì)遇到這種接口中定義了太多的方法,以致于有時(shí)我們?cè)谝恍?shí)現(xiàn)類(lèi)中并不是都需要??创a:
[java] view plain copy
public interface Sourceable {
public void method1();
public void method2();
}
抽象類(lèi)Wrapper2:
[java] view plain copy
public abstract class Wrapper2 implements Sourceable{
public void method1(){}
public void method2(){}
}
[java] view plain copy
public class SourceSub1 extends Wrapper2 {
public void method1(){
System.out.println("the sourceable interface's first Sub1!");
}
}
[java] view plain copy
public class SourceSub2 extends Wrapper2 {
public void method2(){
System.out.println("the sourceable interface's second Sub2!");
}
}
[java] view plain copy
public class WrapperTest {
public static void main(String[] args) {
Sourceable source1 = new SourceSub1();
Sourceable source2 = new SourceSub2();
source1.method1();
source1.method2();
source2.method1();
source2.method2();
}
}
測(cè)試輸出:
the sourceable interface's first Sub1!
the sourceable interface's second Sub2!
達(dá)到了我們的效果!
講了這么多,總結(jié)一下三種適配器模式的應(yīng)用場(chǎng)景:
類(lèi)的適配器模式:當(dāng)希望將一個(gè)類(lèi)轉(zhuǎn)換成滿足另一個(gè)新接口的類(lèi)時(shí),可以使用類(lèi)的適配器模式,創(chuàng)建一個(gè)新類(lèi),繼承原有的類(lèi),實(shí)現(xiàn)新的接口即可。
對(duì)象的適配器模式:當(dāng)希望將一個(gè)對(duì)象轉(zhuǎn)換成滿足另一個(gè)新接口的對(duì)象時(shí),可以創(chuàng)建一個(gè)Wrapper類(lèi),持有原類(lèi)的一個(gè)實(shí)例,在Wrapper類(lèi)的方法中,調(diào)用實(shí)例的方法就行。
接口的適配器模式:當(dāng)不希望實(shí)現(xiàn)一個(gè)接口中所有的方法時(shí),可以創(chuàng)建一個(gè)抽象類(lèi)Wrapper,實(shí)現(xiàn)所有方法,我們寫(xiě)別的類(lèi)的時(shí)候,繼承抽象類(lèi)即可。