head first 設(shè)計(jì)模式-學(xué)習(xí)筆記0(策略模式)

學(xué)習(xí)-輸出-再學(xué)習(xí)箱歧,形成一個(gè)閉環(huán)矾飞,才是最有效果的學(xué)習(xí)方式。如果只有學(xué)習(xí)呀邢,沒(méi)有輸出洒沦,那學(xué)到的只是就像一團(tuán)漿糊塞到你的腦子里,無(wú)法融會(huì)貫通价淌,形成自己的有效知識(shí)體系申眼。因此希望在這里對(duì)自己學(xué)習(xí)的知識(shí)通過(guò)博文的方式進(jìn)行輸出,也希望自己不要半途而廢蝉衣。輸出時(shí)豺型,盡量不看書籍的內(nèi)容,或者只看書籍中的章節(jié)名买乃;憑印象和思考姻氨,復(fù)盤學(xué)習(xí)到的內(nèi)容。復(fù)盤完剪验,再回去對(duì)照書中內(nèi)容肴焊,看看有哪些缺漏。

==================================================================

第一個(gè)例子功戚,介紹了如何使用策略模式娶眷。

本例中,涉及到兩個(gè)重要的設(shè)計(jì)原則:

1. 封裝原則:在軟件設(shè)計(jì)時(shí)要區(qū)分容易發(fā)生變化的部分以及不會(huì)經(jīng)常發(fā)生變化的部分啸臀;對(duì)于容易發(fā)生變化的部分届宠,應(yīng)將其封裝起來(lái),使對(duì)其的改動(dòng)不會(huì)影響到其他部分乘粒。

2. 針對(duì)接口進(jìn)行設(shè)計(jì)而不是針對(duì)實(shí)現(xiàn)進(jìn)行設(shè)計(jì)豌注。

例子:

有一個(gè)游戲開發(fā)公司,設(shè)計(jì)了一款模擬鴨子的游戲灯萍。首先設(shè)計(jì)了一個(gè)類,類中實(shí)現(xiàn)了一些鴨子的基本行為轧铁,比如嘎嘎叫,游泳等等:

class Duck {

public void quack()

{...}

public void swim()

{...}

}

該公司設(shè)計(jì)的所有鴨子類旦棉,都繼承自Duck類齿风,那么這些子類都會(huì)繼承quack和swim行為的代碼。

突然有一天绑洛,市場(chǎng)有新需求救斑,需要對(duì)鴨子增加fly的行為,面對(duì)這個(gè)需求真屯,最直觀最簡(jiǎn)單的做法脸候,就是在Duck類中,新增實(shí)現(xiàn)fly()行為,如下:

class Duck {

public void quack()

{...}

public void swim()

{...}

public void fly()

{...}

}

但是這么做以后纪他,不好的后果出現(xiàn)了鄙煤,所有鴨子的子類都直接繼承了fly行為晾匠。那些本來(lái)不可能飛的鴨子茶袒,也被迫實(shí)現(xiàn)了飛行的功能,比如玩具鴨凉馆,出現(xiàn)了如此大的bug薪寓,程序員緊急修復(fù),因此在玩具鴨類中澜共,覆蓋Duck中的fly接口:

public class RubberDuck extends Duck {

public void fly()

????{

????//do nothing;

????}

...

}

這樣做確實(shí)是臨時(shí)解決了玩具鴨會(huì)飛的尷尬情況向叉。但卻不是長(zhǎng)久之計(jì),假如以后需要新增一種鴨子種類,這種鴨子不僅不會(huì)飛嗦董,也不是嘎嘎叫母谎,而是吱吱叫,那么這個(gè)鴨子類就得同時(shí)覆蓋quack和fly行為京革;如果又要新增一種鴨子奇唤,會(huì)飛,但不會(huì)游泳匹摇,咬扇。利花。侄泽。 這樣每新增一種鴨子,都要檢查是否要覆蓋某些方法拣展, 簡(jiǎn)直是無(wú)窮無(wú)盡的噩夢(mèng)坡垫。

于是優(yōu)化方案1.0:

將Duck類中的quack, fly 等會(huì)變化的行為從類刪除梭灿,提取出來(lái),做成接口的形式:

public interface quackable

{

? ?public? void quack();

}

public interface flyable

{

? ? void fly();

}

當(dāng)要定義一個(gè)鴨子類時(shí)冰悠,先繼承Duck類胎源,然后選擇性地實(shí)現(xiàn)行為接口,比如class RubberDuck就可以改為:

public class RubberDuck extends Duck implements quack

{

? ? public void quack{...}

? ? //不實(shí)現(xiàn)flyable接口屿脐,因此就不會(huì)飛

}

這個(gè)方案的優(yōu)點(diǎn)是涕蚤,再也不用一一檢查哪些類需要重寫,哪些不用的诵,并且每種鴨子可以定義自己的行為万栅。

但是新的問(wèn)題又出現(xiàn)了,有一天西疤,領(lǐng)導(dǎo)要求對(duì)鴨子的fly行為增加一段代碼烦粒。因?yàn)楝F(xiàn)在所有的鴨子類的fly行為都是在各自類中實(shí)現(xiàn)的,所以我們要把所有鴨子的fly代碼都改寫一遍。扰她。兽掰。如果游戲中有幾百種鴨子類型,簡(jiǎn)直無(wú)法想象徒役。這里就牽涉到第一條設(shè)計(jì)原則:封裝的原則孽尽。如果那些擁有相同代碼的函數(shù),從一開始就被設(shè)計(jì)成可復(fù)用的忧勿,就不會(huì)有現(xiàn)在的困惱了杉女。

因此優(yōu)化方案2.0:

仍然設(shè)計(jì)行為接口,flyBehavior, quackBehavior等等,但現(xiàn)在不再由鴨子類來(lái)實(shí)現(xiàn)具體的行為方法鸳吸,而是定義一些行為類熏挎,這些行為類實(shí)現(xiàn)具體不同的fly和quack方法:

public interface quackBehavior

{

?public?void quack();

}

public interface FlyBehavior

{

? ? void fly();

}

class NormalFly implements flyBehavior

{

? ? public void fly()

????{

? ? ? ? //最通用的飛行方式

????}

}

class FlyNoWay implements flyBehavior

{

public void fly()

????{

????????//do nothing; 針對(duì)無(wú)法飛行的鴨子類

????}

}

在Duck類中,持有這些行為接口的引用晌砾,并利用多態(tài)(所謂多態(tài)坎拐,就是對(duì)同一個(gè)消息,可以有不同的響應(yīng)养匈。編寫代碼時(shí)哼勇,不需要關(guān)心是調(diào)用了哪個(gè)子類的方法,只需關(guān)心調(diào)用了哪個(gè)接口乖寒。這里就牽涉到第二個(gè)設(shè)計(jì)原則猴蹂,針對(duì)接口編程而不是針對(duì)實(shí)現(xiàn)編程):

public class Duck

{

? ? FlyBehavior flyBehavior;

? ? public void performFly

????{

? ? ? ? //利用多態(tài),對(duì)不同的flyBehavior的引用楣嘁,會(huì)調(diào)用到不同的fly實(shí)現(xiàn)方法

? ? ? ? flyBehavior.fly();

????}

}

這樣定義一個(gè)鴨子類:

public class RubberDuck extends Duck

{

//構(gòu)造函數(shù):

? ? public RubberDuck()

? ? {

? ??????flyBehavior = new FlyNoway(); //別忘了磅轻,flyBehavior是從父類Duck中繼承的

????}

}

這樣,RubberDuck就不會(huì)飛行逐虚, 而其他鴨子類只要給flyBehavior new一個(gè)NormalFly的行為對(duì)下聋溜,就很方便的設(shè)定了fly行為。而且所有的NormalFly行為代碼都是可復(fù)用的叭爱。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末撮躁,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子买雾,更是在濱河造成了極大的恐慌把曼,老刑警劉巖,帶你破解...
    沈念sama閱讀 211,265評(píng)論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件漓穿,死亡現(xiàn)場(chǎng)離奇詭異嗤军,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)晃危,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,078評(píng)論 2 385
  • 文/潘曉璐 我一進(jìn)店門叙赚,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)老客,“玉大人,你說(shuō)我怎么就攤上這事震叮‰逝椋” “怎么了?”我有些...
    開封第一講書人閱讀 156,852評(píng)論 0 347
  • 文/不壞的土叔 我叫張陵苇瓣,是天一觀的道長(zhǎng)尉间。 經(jīng)常有香客問(wèn)我,道長(zhǎng)钓简,這世上最難降的妖魔是什么乌妒? 我笑而不...
    開封第一講書人閱讀 56,408評(píng)論 1 283
  • 正文 為了忘掉前任汹想,我火速辦了婚禮外邓,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘古掏。我一直安慰自己损话,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,445評(píng)論 5 384
  • 文/花漫 我一把揭開白布槽唾。 她就那樣靜靜地躺著丧枪,像睡著了一般。 火紅的嫁衣襯著肌膚如雪庞萍。 梳的紋絲不亂的頭發(fā)上拧烦,一...
    開封第一講書人閱讀 49,772評(píng)論 1 290
  • 那天,我揣著相機(jī)與錄音钝计,去河邊找鬼恋博。 笑死,一個(gè)胖子當(dāng)著我的面吹牛私恬,可吹牛的內(nèi)容都是我干的债沮。 我是一名探鬼主播,決...
    沈念sama閱讀 38,921評(píng)論 3 406
  • 文/蒼蘭香墨 我猛地睜開眼本鸣,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼疫衩!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起荣德,我...
    開封第一講書人閱讀 37,688評(píng)論 0 266
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤闷煤,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后涮瞻,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體鲤拿,經(jīng)...
    沈念sama閱讀 44,130評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,467評(píng)論 2 325
  • 正文 我和宋清朗相戀三年饲宛,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了皆愉。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,617評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖幕庐,靈堂內(nèi)的尸體忽然破棺而出久锥,到底是詐尸還是另有隱情,我是刑警寧澤异剥,帶...
    沈念sama閱讀 34,276評(píng)論 4 329
  • 正文 年R本政府宣布瑟由,位于F島的核電站,受9級(jí)特大地震影響冤寿,放射性物質(zhì)發(fā)生泄漏歹苦。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,882評(píng)論 3 312
  • 文/蒙蒙 一督怜、第九天 我趴在偏房一處隱蔽的房頂上張望殴瘦。 院中可真熱鬧,春花似錦号杠、人聲如沸蚪腋。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,740評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)屉凯。三九已至,卻和暖如春眼溶,著一層夾襖步出監(jiān)牢的瞬間悠砚,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,967評(píng)論 1 265
  • 我被黑心中介騙來(lái)泰國(guó)打工堂飞, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留灌旧,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 46,315評(píng)論 2 360
  • 正文 我出身青樓酝静,卻偏偏與公主長(zhǎng)得像节榜,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子别智,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,486評(píng)論 2 348

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