《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é)不錯,麻煩大家點擊一下喜歡,便是對我最大的支持和肯定!