適配器其實你們都知道,好比電源適配器,筆記本電壓20多V,而家庭用電220V,因此咱們必須解決讓20v左右的筆記本在220V環境下工做,那麼便須要電源適配器了
。java
與電源適配器類似,在適配器模式中引入了一個被稱爲適配器(Adapter)的包裝類,而它所包裝的對象稱爲適配者(Adaptee),即被適配的類。適配器的實現就是把客戶類的請求轉化爲對適配者的相應接口的調用。也就是說:當客戶類調用適配器的方法時,在適配器類的內部將調用適配者類的方法,而這個過程對客戶類是透明的,客戶類並不直接訪問適配者類。所以,適配器讓那些因爲接口不兼容而不能交互的類能夠一塊兒工做。app
適配器模式能夠將一個類的接口和另外一個類的接口匹配起來,而無須修改原來的適配者接口和抽象目標類接口。適配器模式定義以下:ide
將一個接口轉換成客戶但願的另外一個接口,使接口不兼容的那些類能夠一塊兒工做,其別名爲包裝器(Wrapper)。適配器模式既能夠做爲類結構型模式,也能夠做爲對象結構型模式。this
在適配器模式中,咱們經過增長一個新的適配器類來解決接口不兼容的問題,使得本來沒有任何關係的類能夠協同工做。根據適配器類與適配者類的關係不一樣,適配器模式可分爲對象適配器
和類適配器
兩種,在對象適配器模式中,適配器與適配者之間是關聯關係
;在類適配器模式中,適配器與適配者之間是繼承(或實現)關係
。在實際開發中,對象適配器的使用頻率更高。spa
角色說明:code
Target(目標抽象類)
:目標抽象類定義客戶所需接口,能夠是一個抽象類或接口,也能夠是具體類。Adapter(適配器類)
:適配器能夠調用另外一個接口,做爲一個轉換器,對Adaptee和Target進行適配,適配器類是適配器模式的核心,在對象適配器中,它經過繼承Target並關聯一個Adaptee對象使兩者產生聯繫。Adaptee(適配者類)
:適配者即被適配的角色,它定義了一個已經存在的接口,這個接口須要適配,適配者類通常是一個具體類,包含了客戶但願使用的業務方法,在某些狀況下可能沒有適配者類的源代碼。根據對象適配器模式結構圖,在對象適配器中,客戶端須要調用request()方法,而適配者類Adaptee沒有該方法,可是它所提供的specificRequest()方法倒是客戶端所須要的。爲了使客戶端可以使用適配者類,須要提供一個包裝類Adapter,即適配器類。這個包裝類包裝了一個適配者的實例,從而將客戶端與適配者銜接起來,在適配器的request()方法中調用適配者的specificRequest()方法。由於適配器類與適配者類是關聯關係(也可稱之爲委派關係),因此這種適配器模式稱爲對象適配器模式。客戶端只看到目標接口而不是適配器。適配器實現目標接口。適配器將全部請求委託給Adaptee
cdn
假設你有一個帶有fly()和makeSound()<發出聲音類>方法的Bird類。還有一個帶有squeak()<吱吱叫類>方法的ToyDuck類。假設鳥是咕咕叫,鴨子是吱吱叫,實現了不一樣的接口,如今
我但願鴨子發出鳥叫聲
。因此咱們將使用適配器模式。在這裏,咱們的客戶將是ToyDuck,而adaptee將是Bird。對象
如圖:BirdAdapter將實現ToyDuck接口,類中將關聯一個Bird類,接口,當調用Squea()接口時,適配器將調用Bird接口的makeSound方法,從而實現鴨子發出鳥叫聲的功能。blog
角色分析:繼承
Bird:
// 鳥類實現接口容許飛行和發出 聲音
public interface Bird {
public void fly();
public void makeSound();
}
複製代碼
Sparrow
:
// 麻雀
public class Sparrow implements Bird {
@Override
public void fly() {
System.out.println("正在飛");
}
@Override
public void makeSound() {
System.out.println("咕咕叫");
}
}
複製代碼
ToyDuck:
// 玩具鴨要實現的接口,不會飛,只會吱吱叫
public interface ToyDuck {
// 吱吱吱叫
public void squeak();
}
複製代碼
PlasticToyDuck:
// 塑料玩具鴨
public class PlasticToyDuck implements ToyDuck{
@Override
public void squeak() {
System.out.println("吱吱叫");
}
}
複製代碼
BirdAdapter:
public class BirdAdapter implements ToyDuck {
// 須要實現客戶端但願使用的接口
Bird bird;
public BirdAdapter(Bird bird) {
// 須要引用正在使用的對象
this.bird = bird;
}
@Override
public void squeak() {
bird.makeSound();
}
}
複製代碼
client:
public class Client {
public static void main(String[] args) {
// 麻雀(適配者 Adaptee,被適配的類)
Bird sparrow = new Sparrow();
// 適配器(adapter)
ToyDuck birdAdapter = new BirdAdapter(sparrow);
// 玩具鴨表現的像一隻鳥
System.out.println("我是鴨子,但我發出鳥叫聲:");
birdAdapter.squeak();
}
}
複製代碼
我是鴨子,但我發出鳥叫聲: 咕咕叫
這是類適配器結構圖,adapter須要繼承自目標對象並實現接口,而不少語言都不支持多重繼承,因此這種模式不多使用。
好處:
對象適配器優點:
對象適配器的劣勢:
缺點:
使用場景: