《Head First設計模式》讀書筆記
適配器模式和外觀者模式
一,寫在最前面
1捌省,為什么要將這兩個設計模式寫在一起键思?
不僅這兩個設計模式都比較簡單谦屑,而且我們可以通過這兩個設計模式更好的理解OO思想。
2涛漂,在本章節(jié)的最后會引入了最少知識設計原則赏表。
二,適配器模式
1匈仗,生活中的適配器
如果你自己接過水管或者自己接過洗衣機的水管頭瓢剿,你肯定有過類似的體驗,無論你怎么接悠轩,它都會漏水间狂,然后去店里一問,就知道有水管轉(zhuǎn)換接頭這么個東西火架。他可以讓兩個粗細不同對接不上的水管無縫的對接在一起前标。
2坠韩,面向?qū)ο蟮倪m配器
兩套系統(tǒng)的使用接口不一致,但是你想將兩套系統(tǒng)給對接起來炼列,你就必須設計一個適配器將兩個接口對接起來只搁,這樣你就可以在一個系統(tǒng)中調(diào)用另外一個系統(tǒng)的實現(xiàn)方案。
適配器模式定義:將一個類的接口俭尖,轉(zhuǎn)換成客戶期望的另一個接口氢惋。適配器讓原本接口不兼容的類可以合作無間。
三稽犁,適配器模式(引入書中的demo焰望,而并不只是簡單設計一個水管的接口轉(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();
}
//火雞沒有鴨子飛得遠,那么我們就可以飛五次來假裝成和鴨子一樣的距離珊豹。
@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
四店茶,適配器模式和裝飾者模式
我們乍一看蝶棋,怎么像把火雞給包裝成鴨子了,這不就是裝飾者模式的思想嗎忽妒?
通過仔細分析玩裙,我們可以發(fā)現(xiàn),裝飾者模式主要就是組合和委托段直,那么他們的類型是一定不能變得吃溅,一定得一致,中途也沒有類型的轉(zhuǎn)換鸯檬。但是適配器模式一定要進行接口的轉(zhuǎn)換决侈。這就是他們最大的區(qū)別。
五喧务,外觀者模式
1赖歌,定義
提供一個簡易的接口枉圃,來訪問子系統(tǒng)中的一群接口。外觀定義了一個高層接口庐冯,讓子系統(tǒng)容易使用孽亲。
2,demo背景介紹(例子本身不重要展父,關(guān)鍵理解思想)
比如我們看家庭影院返劲。我們需要打開電視,打開DVD栖茉,打開功放篮绿,設置輸入模式為DVD,設置聲道為雙聲道吕漂,設置房間燈光亮度等等亲配。這么多設置,我們希望將這些動作簡化為一次惶凝。
3吼虎,實現(xiàn)思路
創(chuàng)建一個類,實例化所有需要設置的對象梨睁,然后通過一個命令方法,里面包括了所有的對象的方法娜饵,但是只有一個命令入口坡贺。只需要調(diào)用這一個入口就可以實現(xiàn)所有的設置。
六箱舞,外觀者模式demo代碼
1遍坟,需要設置的對象類:
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,設置一個類來把這些對象命令包裝組合起來
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~
七愿伴,最少知識原則
不要讓太多的類耦合在一起,這樣會導致一個問題:修改系統(tǒng)的一個部分可能會導致修改的部分會影響太多电湘。這就是一個維護與開發(fā)的問題隔节,從長遠看,開發(fā)的時候多花點時間建立一個易于維護的系統(tǒng)是更優(yōu)的選擇寂呛。
不采用下面這種方式怎诫,耦合太多的類:
public float getTemp(){
return station.getThermometer().getTemperture();
}
一般遵循的原則只應該調(diào)用屬于以下范圍的方法:
- 該對象本身
- 被當做方法的參數(shù)而傳遞進來的對象
- 此方法創(chuàng)建或者實例化的任何對象
- 對象的任何組件
如果覺得總結(jié)不錯,麻煩大家點擊一下喜歡贷痪,便是對我最大的支持和肯定幻妓!