設(shè)計模式系列—適配器模式和外觀模式

《Head First設(shè)計模式》讀書筆記

適配器模式和外觀者模式

一,寫在最前面

1,為什么要將這兩個設(shè)計模式寫在一起?

不僅這兩個設(shè)計模式都比較簡單,而且我們可以通過這兩個設(shè)計模式更好的理解OO思想。

2,在本章節(jié)的最后會引入了最少知識設(shè)計原則。

二,適配器模式

1,生活中的適配器

如果你自己接過水管或者自己接過洗衣機(jī)的水管頭,你肯定有過類似的體驗,無論你怎么接,它都會漏水,然后去店里一問,就知道有水管轉(zhuǎn)換接頭這么個東西。他可以讓兩個粗細(xì)不同對接不上的水管無縫的對接在一起。

2,面向?qū)ο蟮倪m配器

兩套系統(tǒng)的使用接口不一致,但是你想將兩套系統(tǒng)給對接起來,你就必須設(shè)計一個適配器將兩個接口對接起來,這樣你就可以在一個系統(tǒng)中調(diào)用另外一個系統(tǒng)的實現(xiàn)方案。
  適配器模式定義:將一個類的接口,轉(zhuǎn)換成客戶期望的另一個接口。適配器讓原本接口不兼容的類可以合作無間。

三,適配器模式(引入書中的demo,而并不只是簡單設(shè)計一個水管的接口轉(zhuǎn)換,后面會介紹到)

1,將火雞偽裝成一個Duck這是我們的目的,看到這句話可能會想到裝飾者模式,注意比較,先看適配器模式代碼,一個Duck接口和一個Turkey接口。

public interface Duck {
public void quak();
public void fly();
}

public interface Turkey {
public void gobble();
public void fly();
}

2,先看兩個Duck和Turkey實現(xiàn)類

public class MallarDuck implements Duck{

@Override
public void quak() {
    System.out.println("Quack~");
}

@Override
public void fly() {
    System.out.println("I'm flying~");
}
}

public class WildTurkey implements Turkey{

@Override
public void gobble() {
    System.out.println("Gobble gobble");
}

@Override
public void fly() {
    System.out.println("I'm flying a short distance");
}
}

3,到這里,分別有一個Duck具體類和一個WildTurkey具體類,那么我就需要一個adapter來將wildTurkey轉(zhuǎn)換成Duck接口。

public class TurkeyAdapter implements Duck{
private Turkey turkey;

public TurkeyAdapter(Turkey turkey) {
    this.turkey = turkey;
}

@Override
public void quak() {
    turkey.gobble();
}

//火雞沒有鴨子飛得遠(yuǎn),那么我們就可以飛五次來假裝成和鴨子一樣的距離。
@Override
public void fly() {
    for(int i = 0; i < 5 ; i++){
        turkey.fly();
    }
}
}

4,然后我們看看測試代碼:

public class Test {
public static void main(String[] args) {
    MallarDuck duck = new MallarDuck();
    duck.quak();
    duck.fly();
    System.out.println("--------------");
    WildTurkey turkey = new WildTurkey();
    TurkeyAdapter adapter = new TurkeyAdapter(turkey);
    adapter.quak();
    adapter.fly();
}
}

5,測試結(jié)果

Quack~
I'm flying~
--------------
Gobble gobble
I'm flying a short distance
I'm flying a short distance
I'm flying a short distance
I'm flying a short distance
I'm flying a short distance

四,適配器模式和裝飾者模式

我們乍一看,怎么像把火雞給包裝成鴨子了,這不就是裝飾者模式的思想嗎?
  通過仔細(xì)分析,我們可以發(fā)現(xiàn),裝飾者模式主要就是組合和委托,那么他們的類型是一定不能變得,一定得一致,中途也沒有類型的轉(zhuǎn)換。但是適配器模式一定要進(jìn)行接口的轉(zhuǎn)換。這就是他們最大的區(qū)別。

五,外觀者模式

1,定義

提供一個簡易的接口,來訪問子系統(tǒng)中的一群接口。外觀定義了一個高層接口,讓子系統(tǒng)容易使用。

2,demo背景介紹(例子本身不重要,關(guān)鍵理解思想)

比如我們看家庭影院。我們需要打開電視,打開DVD,打開功放,設(shè)置輸入模式為DVD,設(shè)置聲道為雙聲道,設(shè)置房間燈光亮度等等。這么多設(shè)置,我們希望將這些動作簡化為一次。

3,實現(xiàn)思路

創(chuàng)建一個類,實例化所有需要設(shè)置的對象,然后通過一個命令方法,里面包括了所有的對象的方法,但是只有一個命令入口。只需要調(diào)用這一個入口就可以實現(xiàn)所有的設(shè)置。

六,外觀者模式demo代碼

1,需要設(shè)置的對象類:

public class Amplifier {
public void on(){
    System.out.println("The amplifier is on~");
}
}

public class Light {
public void adjust(){
    System.out.println("Adjuast the light~");
}
}

public class TV {
public void on(){
    System.out.println("The TV is on~");
}
}

2,設(shè)置一個類來把這些對象命令包裝組合起來

public class HomeTheater {
Amplifier amp;
Light light;
TV tv;
public HomeTheater(Amplifier amp,Light light,TV tv) {
    this.amp = amp;
    this.light = light;
    this.tv = tv;
}
public void WatchMove(){
    amp.on();
    light.adjust();
    tv.on();
}
}

3,測試類

public class Test {
public static void main(String[] args) {
    Amplifier amp = new Amplifier();
    Light light = new Light();
    TV tv = new TV();
    HomeTheater homeTheater = new HomeTheater(amp, light, tv);
    homeTheater.WatchMove();
}
}

4,輸出結(jié)果

The amplifier is on~
Adjuast the light~
The TV is on~

七,最少知識原則

不要讓太多的類耦合在一起,這樣會導(dǎo)致一個問題:修改系統(tǒng)的一個部分可能會導(dǎo)致修改的部分會影響太多。這就是一個維護(hù)與開發(fā)的問題,從長遠(yuǎn)看,開發(fā)的時候多花點時間建立一個易于維護(hù)的系統(tǒng)是更優(yōu)的選擇。
  不采用下面這種方式,耦合太多的類:

public float getTemp(){
    return station.getThermometer().getTemperture();
}

一般遵循的原則只應(yīng)該調(diào)用屬于以下范圍的方法:

  • 該對象本身
  • 被當(dāng)做方法的參數(shù)而傳遞進(jìn)來的對象
  • 此方法創(chuàng)建或者實例化的任何對象
  • 對象的任何組件

如果覺得總結(jié)不錯,麻煩大家點擊一下喜歡,便是對我最大的支持和肯定!

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

推薦閱讀更多精彩內(nèi)容