版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
1、當(dāng)我們掌握了Java 的語(yǔ)法,當(dāng)我們了解了面向?qū)ο蟮姆庋b、繼承、多態(tài)等特性,當(dāng)我們可以用Swing 、Servlet 、JSP技術(shù)構(gòu)建桌面以及 Web 應(yīng)用,不意味著我們可以寫出面向?qū)ο蟮某绦?,不意味著我們可以很好的?shí)現(xiàn)代碼復(fù)用,彈性維護(hù),不意味著我們可以實(shí)現(xiàn)在維護(hù)、擴(kuò)展基礎(chǔ)上的代碼復(fù)用。一把刀,可以使你制敵于無(wú)形而于江湖揚(yáng)名,也可以只是一把利刃而使你切菜平靜。Java,就是這把刀,它的威力取決于你使用的方式。當(dāng)我們陷入無(wú)盡無(wú)止重復(fù)代碼的泥沼,當(dāng)我們面臨牽一發(fā)而動(dòng)全身的維護(hù)惡夢(mèng), 你應(yīng)該想起 “設(shè)計(jì)模式”這個(gè)行動(dòng)秘笈。面向?qū)ο蟮木x,看似平淡,其實(shí)要經(jīng)過(guò)艱苦實(shí)踐才能成功。而構(gòu)造OO 系統(tǒng)的隱含
2、經(jīng)驗(yàn)于是被前人搜集而成并冠以“設(shè)計(jì)模式 ”之名。我們應(yīng)該在編碼行動(dòng)初始就攜帶以它。接下來(lái),讓我們步 “四人組 ”先行者之后,用中國(guó)文字、用實(shí)際案例領(lǐng)略模式于我們代碼煥然一新的改變:設(shè)計(jì)模式解讀之一:策略模式1. 模式定義把會(huì)變化的內(nèi)容取出并封裝起來(lái),以便以后可以輕易地改動(dòng)或擴(kuò)充部分,而不影響不需要變化的其他部分;2. 問(wèn)題緣起當(dāng)涉及至代碼維護(hù)時(shí),為了復(fù)用目的而使用繼承,結(jié)局并不完美。對(duì)父類的修改,會(huì)影響到子類型。在超類中增加的方法,會(huì)導(dǎo)致子類型有該方法,甚至連那些不該具備該方法的子類型也無(wú)法免除。示例,一個(gè)鴨子類型:public abstract class Duck / 所有的鴨子均會(huì)叫以及
3、游泳,所以父類中處理這部分代碼public void quack() System.out.println(Quack);public void swim() System.out.println(All ducks float, even decoys.);/ 因?yàn)槊糠N鴨子的外觀是不同的,所以父類中該方法是抽象的,由子類型自己完成。public abstract void display();public class MallardDuck extends Duck / 野鴨外觀顯示為綠頭public void display() System.out.println(Green head.
4、);public class RedHeadDuck extends Duck / 紅頭鴨顯示為紅頭public void display() System.out.println(Red head.);public class RubberDuck extends Duck / 橡皮鴨叫聲為吱吱叫,所以重寫父類以改寫行為public void quack() System.out.println(Squeak);/ 橡皮鴨顯示為黃頭public void display() System.out.println(Yellow head.);上述代碼,初始實(shí)現(xiàn)得非常好。現(xiàn)在我們?nèi)绻o Duck
5、.java 中加入 fly() 方法的話,那么在子類型中均有了該方法, 于是我們看到了 會(huì)飛的橡皮鴨子, 你看過(guò)嗎?當(dāng)然, 我們可以在子類中通過(guò)空實(shí)現(xiàn)重寫該方法以解決該方法對(duì)于子類型的影響。但是父類中再增加其它的方法呢?通過(guò)繼承在父類中提供行為,會(huì)導(dǎo)致以下缺點(diǎn):a. 代碼在多個(gè)子類中重復(fù);b. 運(yùn)行時(shí)的行為不容易改變;c. 改變會(huì)牽一發(fā)動(dòng)全身,造成部分子類型不想要的改變;好啦,還是剛才鴨子的例子,你也許想到使用接口,將飛的行為、叫的行為定義為接口,然后讓Duck的各種子類型實(shí)現(xiàn)這些接口。這時(shí)侯代碼類似于:public abstract class Duck / 將變化的行為fly()以及 qu
6、ake() 從 Duck 類中分離出去定義形成接口,有需求的子類中自行去實(shí)現(xiàn)public void swim() System.out.println(All ducks float, even decoys.);public abstract void display();/ 變化的 fly() 行為定義形成的接口public interface FlyBehavior void fly();/ 變化的 quack() 行為定義形成的接口public interface QuackBehavior void quack();/ 野鴨子會(huì)飛以及叫,所以實(shí)現(xiàn)接口FlyBehavior, Quac
7、kBehaviorpublic class MallardDuck extends Duck implements FlyBehavior, QuackBehavior public void display() System.out.println(Green head.);public void fly() System.out.println(Fly.);public void quack() System.out.println(Quack.);/ 紅頭鴨子會(huì)飛以及叫,所以也實(shí)現(xiàn)接口FlyBehavior, QuackBehaviorpublic class RedHeadDuck e
8、xtends Duck implements FlyBehavior, QuackBehavior public void display() System.out.println(Red head.);public void fly() System.out.println(Fly.);public void quack() System.out.println(Quack.);/ 橡皮鴨不會(huì)飛,但會(huì)吱吱叫,所以只實(shí)現(xiàn)接口QuackBehaviorpublic class RubberDuck extends Duck implements QuackBehavior/ 橡皮鴨叫聲為吱吱叫p
9、ublic void quack() System.out.println(Squeak);/ 橡皮鴨顯示為黃頭public void display() System.out.println(Yellow head.);上述代碼雖然解決了一部分問(wèn)題, 讓子類型可以有選擇地提供一些行為 (例如 fly() 方法將不會(huì)出現(xiàn)在橡皮鴨中 ). 但我們也看到, 野鴨子 MallardDuck.java 和紅頭鴨子 RedHeadDuck.java 的一些相同行為代碼不能得到重復(fù)使用。很大程度上這是從一個(gè)火坑跳到另一個(gè)火坑。在一段程序之后,讓我們從細(xì)節(jié)中跳出來(lái),關(guān)注一些共性問(wèn)題。不管使用什么語(yǔ)言,構(gòu)建什
10、么應(yīng)用,在軟件開(kāi)發(fā)上,一直伴隨著的不變的真理是:需要一直在變化。不管當(dāng)初軟件設(shè)計(jì)得多好,一段時(shí)間之后,總是需要成長(zhǎng)與改變,否則軟件就會(huì)死亡。我們知道,繼承在某種程度上可以實(shí)現(xiàn)代碼重用,但是父類( 例如鴨子類Duck) 的行為在子類型中是不斷變化的,讓所有子類型都有這些行為是不恰當(dāng)?shù)?。我們可以將這些行為定義為接口,讓Duck 的各種子類型去實(shí)現(xiàn),但接口不具有實(shí)現(xiàn)代碼,所以實(shí)現(xiàn)接口無(wú)法達(dá)到代碼復(fù)用。這意味著,當(dāng)我們需要修改某個(gè)行為,必須往下追蹤并在每一個(gè)定義此行為的類中修改它,一不小心,會(huì)造成新的錯(cuò)誤。設(shè)計(jì)原則:把應(yīng)用中變化的地方獨(dú)立出來(lái),不要和那些不需要變化的代碼混在一起。這樣代碼變化引起的不經(jīng)
11、意后果變少,系統(tǒng)變得更有彈性。按照上述設(shè)計(jì)原則,我們重新審視之前的Duck 代碼。1) 分開(kāi)變化的內(nèi)容和不變的內(nèi)容Duck 類中的行為Duck 類中的行為fly(), quack(),每個(gè)子類型可能有自己特有的表現(xiàn),這就是所謂的變化的內(nèi)容。swim()每個(gè)子類型的表現(xiàn)均相同,這就是所謂不變的內(nèi)容。我們將變化的內(nèi)容從 Duck() 類中剝離出來(lái)單獨(dú)定義形成接口以及一系列的實(shí)現(xiàn)類型。將變化的內(nèi)容定義形成接口可實(shí)現(xiàn)變化內(nèi)容和不變內(nèi)容的剝離。其實(shí)現(xiàn)類型可實(shí)現(xiàn)變化內(nèi)容的重用。這些實(shí)現(xiàn)類并非Duck.java 的子類型,而是專門的一組實(shí)現(xiàn)類,稱之為 行為類 。由行為類而不是Duck.java的子類型來(lái)實(shí)現(xiàn)
12、接口。這樣,才能保證變化的行為獨(dú)立于不變的內(nèi)容。于是我們有:變化的內(nèi)容:/ 變化的 fly() 行為定義形成的接口public interface FlyBehavior void fly();/ 變化的 fly() 行為的實(shí)現(xiàn)類之一public class FlyWithWings implements FlyBehavior public void fly() System.out.println(Im flying.);/ 變化的 fly() 行為的實(shí)現(xiàn)類之二public class FlyNoWay implements FlyBehavior public void fly() Sy
13、stem.out.println(I cant fly.);-/ 變化的 quack() 行為定義形成的接口public interface QuackBehavior void quack();/ 變化的 quack() 行為實(shí)現(xiàn)類之一public class Quack implements QuackBehavior public void quack() System.out.println(Quack);/ 變化的 quack() 行為實(shí)現(xiàn)類之二public class Squeak implements QuackBehavior public void quack() Syste
14、m.out.println(Squeak.);/ 變化的 quack() 行為實(shí)現(xiàn)類之三public class MuteQuack implements QuackBehavior public void quack() System.out.println();通過(guò)以上設(shè)計(jì),fly() 行為以及quack() 行為已經(jīng)和Duck.java 沒(méi)有什么關(guān)系,可以充分得到復(fù)用。而且我們很容易增加新的行為 , 既不影響現(xiàn)有的行為,也不影響在面向?qū)ο笾行袨椴皇求w現(xiàn)為方法嗎?為什么現(xiàn)在被定義形成類Duck.java 。但是,大家可能有個(gè)疑問(wèn),就是(例如 Squeak.java) ?在 OO 中,類代表
15、的 東西 一般是既有狀態(tài)(實(shí)例變量)又有方法。只是在本例中碰巧 東西 是個(gè)行為。既使是行為,也有屬性及方法,例如飛行行為,也需要一些屬性記錄飛行的狀態(tài),如飛行高度、速度等。2) 整合變化的內(nèi)容和不變的內(nèi)容Duck.java 將 fly() 以及 quack() 的行為委托給行為類處理。不變的內(nèi)容:public abstract class Duck / 將行為類聲明為接口類型,降低對(duì)行為實(shí)現(xiàn)類型的依賴FlyBehavior flyBehavior;QuackBehavior quackBehavior;public void performFly() / 不自行處理fly() 行為,而是委拖給
16、引用flyBehavior 所指向的行為對(duì)象flyBehavior.fly();public void performQuack() quackBehavior.quack();public void swim() System.out.println(All ducks float, even decoys.);public abstract void display();Duck.java 不關(guān)心如何進(jìn)行fly() 以及 quack(),這些細(xì)節(jié)交由具體的行為類完成。public class MallardDuck extends Duckpublic MallardDuck() flyB
17、ehavior=new FlyWithWings();quackBehavior=new Quack();public void display() System.out.println(Green head.);測(cè)試類:public class DuckTest public static void main(String args) Duck duck=new MallardDuck();duck.performFly();duck.performQuack();在 Duck.java 子類型 MallardDuck.java 的構(gòu)造方法中,直接實(shí)例化行為類型, 在編譯的時(shí)侯便指定具體行為
18、類型。當(dāng)然,我們可以:1) 我們可以通過(guò)工廠模式或其它模式進(jìn)一步解藕( 可參考后續(xù)模式講解 );2) 或做到在運(yùn)行時(shí)動(dòng)態(tài)地改變行為。3) 動(dòng)態(tài)設(shè)定行為在父類 Duck.java 中增加設(shè)定行為類型的 setter 方法,接受行為類型對(duì)象的參數(shù)傳入。為了降藕,行為參數(shù)被聲明為接口類型。這樣,既便在運(yùn)行時(shí),也可以通過(guò)調(diào)用這二個(gè)方法以改變行為。public abstract class Duck / 在剛才 Duck.java 中加入以下二個(gè)方法。public void setFlyBehavior(FlyBehavior flyBehavior) this.flyBehavior=flyBehavior;public void setQuackBehavior(QuackBehavior quackBehavior) this.quackBehavior=quackBehavior;/ 其它方法同,省略 .測(cè)試類:public class DuckTest public static voi
溫馨提示
- 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 深圳市勞務(wù)員考試題庫(kù)及答案
- 人衛(wèi)技師考試題庫(kù)及答案
- 輔警職責(zé)培訓(xùn)課件
- 輔警作風(fēng)建設(shè)培訓(xùn)課件
- 護(hù)理對(duì)醫(yī)療質(zhì)量改進(jìn)的貢獻(xiàn)
- 2026年深圳中考語(yǔ)文文言文翻譯專項(xiàng)試卷(附答案可下載)
- 2026年深圳中考英語(yǔ)臨考沖刺押題試卷(附答案可下載)
- 2026年深圳中考物理易混考點(diǎn)辨析試卷(附答案可下載)
- 2026年深圳中考生物專題整合訓(xùn)練試卷(附答案可下載)
- 2026年深圳中考生物名師原創(chuàng)預(yù)測(cè)試卷(附答案可下載)
- 2026重慶水利電力職業(yè)技術(shù)學(xué)院高層次人才招聘筆試參考題庫(kù)及答案解析
- 2026天津市津南創(chuàng)騰經(jīng)濟(jì)開(kāi)發(fā)有限公司招聘8人筆試參考題庫(kù)及答案解析
- 特種作業(yè)培訓(xùn)課件模板
- 2025年時(shí)事政治知識(shí)考試試題題庫(kù)試題附答案完整版
- 高校宿舍管理員培訓(xùn)課件
- 河南省開(kāi)封市2026屆高三年級(jí)第一次質(zhì)量檢測(cè)歷史試題卷+答案
- 員工通勤安全培訓(xùn)課件
- 歲末年初安全知識(shí)培訓(xùn)課件
- 陶瓷工藝品彩繪師崗后測(cè)試考核試卷含答案
- 全國(guó)秸稈綜合利用重點(diǎn)縣秸稈還田監(jiān)測(cè)工作方案
- 廣西壯族自治區(qū)工業(yè)和信息化廳直屬部分科研事業(yè)單位2025年度公開(kāi)招聘工作人員備考題庫(kù)參考答案詳解
評(píng)論
0/150
提交評(píng)論