適配器模式的官方定義是:適配器模式把一個(gè)類的接口變換成客戶端所期待的另一種接口捎拯,從而使原本因接口不匹配而無法在一起工作的兩個(gè)類能夠在一起工作给僵。
舉例說明:很多的插座都是兩孔的,但是你的臺(tái)燈的電源線卻有三個(gè)腳鹃骂,這樣你無法直接將臺(tái)燈直接使用,要想三腳的電源線插到兩孔的插座上你需要買一個(gè)(三腳-兩孔)的轉(zhuǎn)換器來將它們適配起來滨嘱,而這個(gè)轉(zhuǎn)換器我們稱之為適配器冈涧。
適配器模式分為3類:類的適配器模式碰煌、對(duì)象的適配器模式、接口的適配器模式撼港。
1.類的適配器模式:
你有一個(gè)源類坪它,他有一個(gè)method1()方法,如下
public class source{
public void method1(){
System.out.println("this is method1");
}
}
但是你的客戶期望的接口并不是這個(gè)源類這樣的帝牡,他不僅僅需要有method1方法還需要有method2方法往毡。如下:
public interface targrt{
public void method1();
public void method2();
}
此時(shí),要想滿足目標(biāo)接口你需要?jiǎng)?chuàng)建一個(gè)適配器靶溜,它既有source的method1方法還有類interface的method方法开瞭,如下:
class adapter extends source implements targrt{
/*
* method1方法可以直接從source繼承過來
* 自己實(shí)現(xiàn)接口中的method2方法
*/
@Override
public void method2() {
System.out.println("this is method2");
}
}
但是這樣做是有一個(gè)大問題就是當(dāng)Source類有兩個(gè)時(shí),由于Java時(shí)單繼承的罩息,無法通過類適配器模式來完成嗤详。如:
public class source1{
public void method3(){
System.out.println("this is method3");
}
}
2.對(duì)象適配器模式
對(duì)象適配器模式跟類適配其模式相比僅僅是改變了Adapter類。如下:
class adapter implements targrt{
private Source source;
private Source1 source1;
public Adapter(Source source,Source1 source1){
this.source = source;
this.source1 = souce1;
}
public void method1(){
this.source.method1();
}
public void method3(){
this.source1.method3();
}
/*
* 自己實(shí)現(xiàn)接口中的method2方法
*/
@Override
public void method2() {
System.out.println("this is method2");
}
}
對(duì)象適配器模式是將源方法的實(shí)現(xiàn)通過持有一個(gè)源實(shí)例的形式瓷炮,這樣當(dāng)有多個(gè)source類時(shí)可以通過持有多個(gè)實(shí)例來實(shí)現(xiàn)葱色,解決了類適配其模式的問題。
3.缺省適配模式
缺省適配(Default Adapter)模式為一個(gè)接口提供缺省實(shí)現(xiàn)娘香,這樣子類型可以從這個(gè)缺省實(shí)現(xiàn)進(jìn)行擴(kuò)展苍狰,而不必從原有接口進(jìn)行擴(kuò)展办龄。
很多時(shí)候我們的寫的一個(gè)類需要繼承一個(gè)目標(biāo)接口,但是這個(gè)目標(biāo)接口有很多方法我們用不上淋昭,我們想只實(shí)現(xiàn)其中想要的方法時(shí)可以使用缺省適配器模式俐填。首先定義一個(gè)抽象類來繼承目標(biāo)接口,然后用自己的類去繼承這個(gè)抽象類的方式實(shí)現(xiàn)目標(biāo)接口响牛。如下:
/*
* 目標(biāo)接口玷禽,其中我們只想要method1方法
*/
public interface Target{
public void method1();
public void method2();
}
public abstract class Adapter implements Target{
public void method1(){}
public void method2(){}
}
我們寫的類(只去實(shí)現(xiàn)method1方法):
public class MyClass extends Adapter{
public void method1(){
System.out.println("this is method1");
}
}
最后的Test類:
public class Test {
public static void main(String[] args) {
Target target = new MyClass();
}
}
總結(jié):
類的適配器模式:當(dāng)希望將一個(gè)類轉(zhuǎn)換成滿足另一個(gè)新接口的類時(shí),可以使用類的適配器模式呀打,創(chuàng)建一個(gè)新類,繼承原有的類糯笙,實(shí)現(xiàn)新的接口即可贬丛。
對(duì)象的適配器模式:當(dāng)希望將一個(gè)對(duì)象轉(zhuǎn)換成滿足另一個(gè)新接口的對(duì)象時(shí),可以創(chuàng)建一個(gè)類给涕,持有原類的一個(gè)實(shí)例豺憔,在類的方法中,調(diào)用實(shí)例的方法就行够庙。
缺省適配器模式:當(dāng)不希望實(shí)現(xiàn)一個(gè)接口中所有的方法時(shí)恭应,可以創(chuàng)建一個(gè)抽象類,實(shí)現(xiàn)所有方法耘眨,我們寫別的類的時(shí)候昼榛,繼承抽象類即可。
適配器模式的缺點(diǎn):
過多的使用適配器剔难,會(huì)讓系統(tǒng)非常零亂胆屿,不易整體進(jìn)行把握。比如偶宫,明明看到調(diào)用的是A接口非迹,其實(shí)內(nèi)部被適配成了B接口的實(shí)現(xiàn),一個(gè)系統(tǒng)如果太多出現(xiàn)這種情況纯趋,無異于一場(chǎng)災(zāi)難憎兽。因此如果不是很有必要,可以不使用適配器吵冒,而是直接對(duì)系統(tǒng)進(jìn)行重構(gòu)纯命。