摘要:不會叫鴨子呱呱呱叫。。。。。。此時我剛剛寫的例子基于一個策略模式思想寫的。感謝你看到這里,策略模式部分結(jié)束,本人文筆隨便,若有不足或錯誤之處望給予指點,度彎腰很快我會發(fā)布下一個設(shè)計模式內(nèi)容,生命不息,編程不止參考書籍設(shè)計模式
并不是每個自稱自己是個OO的人,他就一定能運(yùn)用好OOP。
普通程序員寫的東西好比一把普通鑰匙,一把鑰匙只能開一個門,而高級程序員就會“造”萬能鑰匙。
我以前所理解的“簡單”就是一把鑰匙開一把鎖的模式,僅僅只是著眼于解決現(xiàn)在的問題,而設(shè)計模式的“復(fù)雜”在于它需要造出具有“通用性”的萬能鑰匙。而我以前寫的代碼就是前者,這個“簡單”不是功能的簡單,而是設(shè)計的簡單。簡單的設(shè)計意味著缺少靈活性,代碼很鋼硬,僅僅只是面向過程,一步操作緊挨著下一步。
要使代碼可被反復(fù)使用,請用’設(shè)計模式’對你的代碼進(jìn)行設(shè)計.
模擬鴨子程序開始了。
首先來一張類圖,這是鴨子程序原始狀態(tài)
而此時我們需要添加一個新功能:鴨子飛功能(吐槽:明明很多鴨子不會飛)
這很簡單,難不倒我們“有OO思想”的人
但這樣的設(shè)計運(yùn)用在下面拓展的程序上會變成什么呢?
哇哦,很明顯橡皮鴨子不能飛,而在此設(shè)計中使用繼承(extends)就變得不合理了,
但是我們可以投機(jī)取巧一點,變成如下圖
這樣小聰明的方法,恐怕我自己看的都不能直視了....
很明顯對于繼承在這個設(shè)計當(dāng)中很幾個致命的地方
1:各個鴨子子類繼承父類時,使得代碼在多個子類中重復(fù)
2:沒有拓展性,對于改變會費(fèi)勁
3:往往改變一點地方很多地方就都要跟著改變,找出其他鴨子類中不想要的改變,牽一發(fā)而動全身。
設(shè)計原則一:找出應(yīng)用中可能需要變化之處,把它們獨(dú)立出來,不要和那些不需要變化的代碼混在一起
注:當(dāng)每次有新的需求的時候,就會使某方面發(fā)生變化,那么你就可以確定,這部分的代碼就需要被抽出來,和其他穩(wěn)定的代碼有所區(qū)分,這樣使得代碼變化引起的不經(jīng)意后果變少,系統(tǒng)變得更加富有彈性。
設(shè)計原則二:針對接口編程,而不是針對實現(xiàn)編程。
注:從現(xiàn)在開始我們編寫的代碼要富有彈性,讓其運(yùn)行時能“動態(tài)”的改變飛行或者呱呱叫行為
進(jìn)行一點小改變
這里將飛行和叫的行為各自“抽象”出來成接口,這兩個行為被分開成兩個類,這兩個類專門為提供某行為的實現(xiàn)提供接口。不同與之前設(shè)計:行為來自Duck父類中子類的具體實現(xiàn),或是繼承某個接口并由子類自行實現(xiàn)而來。這兩種做法都依賴“實現(xiàn)”。而此時子類將使用接口所代表的行為,所以實際的“實現(xiàn)”不會被綁死在鴨子的子類中。(特定的具體行為編寫在實現(xiàn)了FlyBehavior和QuackBehavior接口的實現(xiàn)類中)
這里放出具體行為設(shè)計
注:此時飛行和叫的動作(接口)可以被其他對象復(fù)用,此時這兩個行為和鴨子類(Duck)無關(guān)了,而且往后加入新的行為也不怕了大量修改代碼了。
鴨子父類:
package Entity; import Interface.FlyBehavior; import Interface.QuackBehavior; //鴨子父類 public class Duck { // 添加兩個接口變量 FlyBehavior flyBehavior;// 每只鴨子都會引用完成FlyBehavior接口的對象 QuackBehavior quackBehavior;// 每只鴨子都會引用完成QuackBehavior接口的對象 public FlyBehavior getFlyBehavior() { return flyBehavior; } public void setFlyBehavior(FlyBehavior flyBehavior) { this.flyBehavior = flyBehavior; } public QuackBehavior getQuackBehavior() { return quackBehavior; } public void setQuackBehavior(QuackBehavior quackBehavior) { this.quackBehavior = quackBehavior; } public Duck() { } public void swim() { System.out.println("鴨子游泳。。。。。。"); } // 動作 public void display() { System.out.println("每只鴨子都會動"); } // 這些方法取代fly(),quack() // 鴨子對象不親自處理呱呱呱叫行為,而是委托給quackBehavior引用對象 public void performQuack() { quackBehavior.quack(); } // 鴨子對象不親自處理飛行為,而是委托給flyBehavior引用對象 public void performFly() { flyBehavior.fly(); }; }
飛行和叫動作接口
package Interface; //飛行接口 public interface FlyBehavior { public void fly(); }
package Interface; //鴨子叫接口 public interface QuackBehavior { public void quack(); }
//綠頭鴨和橡皮鴨類
package Entity; import Implements.FlyWithWings; import Implements.Quack; //綠頭鴨子類 public class MallardDuck extends Duck { @Override public void display() { System.out.println("綠頭鴨子"); } /* 當(dāng)MallardDuck被實例化時, * 構(gòu)造器會把繼承來的quackBehavior,flyBehavior * 實例變量初始化成Quack,F(xiàn)lyWithWings的類型 * Quack,F(xiàn)lyWithWings分別是接口的實現(xiàn)類 * */ public MallardDuck() { quackBehavior = new Quack(); flyBehavior = new FlyWithWings(); } }
package Entity; import Implements.FlyNoWay; import Implements.Squeak; public class RubberDuck extends Duck { //橡皮鴨類 @Override public void display() { System.out.println("我是一只橡皮鴨"); } public RubberDuck() { quackBehavior = new Squeak(); flyBehavior = new FlyNoWay(); } }
各個行為的具體實現(xiàn)類,都實現(xiàn)了接口
package Implements; import Interface.FlyBehavior; public class FlyNoWay implements FlyBehavior { @Override public void fly() { System.out.println("不會飛"); } }
package Implements; import Interface.FlyBehavior; public class FlyWithWings implements FlyBehavior { @Override public void fly() { System.out.println("鴨子飛起來了。。。。。。"); } }
package Implements; import Interface.QuackBehavior; public class MuteQuack implements QuackBehavior { @Override public void quack() { System.out.println("不會叫"); } }
package Implements; import Interface.QuackBehavior; public class Quack implements QuackBehavior { @Override public void quack() { System.out.println("鴨子呱呱呱叫。。。。。。"); } }
package Implements; import Interface.QuackBehavior; public class Squeak implements QuackBehavior { @Override public void quack() { System.out.println("鴨子吱吱吱叫。。。。。。"); } }
測試類
package TestMain; import Entity.Duck; import Entity.MallardDuck; import Entity.RubberDuck; public class TestMain { public static void main(String[] args) { //這里使用多態(tài),讓Duck知道我們要創(chuàng)建一只綠頭鴨 Duck d = new MallardDuck(); //重載方法 d.display(); d.performQuack(); d.performFly(); System.out.print(" "); Duck a=new RubberDuck(); a.display(); a.performQuack(); a.performFly(); } }
效果:
設(shè)計原則三:多用組合,少用繼承。
注:使用組合建立系統(tǒng)具有很大的彈性,不僅可將算法封裝成類,更可以“動態(tài)的改變行為”,只要組合對象符合正確的接口標(biāo)準(zhǔn)即可。
此時我剛剛寫的例子基于一個策略模式思想寫的。當(dāng)然你可能會問:“用這個設(shè)計模式到底有什么用呢?這樣功能我也能實現(xiàn)了,干嘛要搞的那么復(fù)雜?”。對此我不能用專業(yè)的思想去回答這樣的疑問,我只能說隨著自己學(xué)習(xí)的不斷深入往往很多以前自認(rèn)為對的東西,其實是不正確的。
策略模式要點:
1:良好的OO設(shè)計必須具備可復(fù)用性、可擴(kuò)充性、可維護(hù)性三個特征
2:模式不是代碼,而是針對設(shè)計問題的通用解決方案。
3:大多數(shù)的模式都允許系統(tǒng)局部改變獨(dú)立于其他部分。
4:記著把系統(tǒng)中會改變的部分抽出來封裝
5:模式會讓開發(fā)人員之間有共同的語言,而且會讓自己少走很多坑
這里我想說一點,很多人都覺得設(shè)計模式跟算法一樣都是可有可無的東西,我覺得用設(shè)計模式是著眼于未來,可以提高系統(tǒng)的擴(kuò)展性,減少重復(fù)勞動,雖然有的時候可能會增加工作量,但比起后期無止境的維護(hù),這點反而不算什么,而設(shè)計模式是不會提高系統(tǒng)運(yùn)行速度的,但我認(rèn)為設(shè)計模式非常重要,包括帶我的前輩程序員都教導(dǎo)我腦中要有模式概念,當(dāng)然這個要因人而異。
感謝你看到這里,策略模式部分結(jié)束,本人文筆隨便,若有不足或錯誤之處望給予指點,90度彎腰~很快我會發(fā)布下一個設(shè)計模式內(nèi)容,生命不息,編程不止!
參考書籍:《Head First 設(shè)計模式》
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/67596.html
摘要:本篇主要講述中使用函數(shù)來實現(xiàn)策略模式和命令模式,最后總結(jié)出這種做法背后的思想。 《流暢的Python》筆記。本篇主要講述Python中使用函數(shù)來實現(xiàn)策略模式和命令模式,最后總結(jié)出這種做法背后的思想。 1. 重構(gòu)策略模式 策略模式如果用面向?qū)ο蟮乃枷雭砗唵谓忉尩脑?,其實就是多態(tài)。父類指向子類,根據(jù)子類對同一方法的不同重寫,得到不同結(jié)果。 1.1 經(jīng)典的策略模式 下圖是經(jīng)典的策略模式的U...
摘要:設(shè)計模式的定義在面向?qū)ο筌浖O(shè)計過程中針對特定問題的簡潔而優(yōu)雅的解決方案。從前由于使用的局限性,和做的應(yīng)用相對簡單,不被重視,就更談不上設(shè)計模式的問題。 ‘從大處著眼,從小處著手’,以前對這句話一知半解,自從踏出校門走入社會,開始工作以來,有了越來越深的理解,偶有發(fā)現(xiàn)這句話用在程序開發(fā)中也有用,所以,近段時間開始嘗試著分析jQuery源碼,分析angularjs源碼,學(xué)習(xí)設(shè)計模式。 設(shè)...
摘要:下圖就是第一版當(dāng)時的樣子年圍繞他們的發(fā)起了積極的營銷策略,比如像前文提到的那兩次小花招,借此向人們進(jìn)一步傳遞了的主張。從年到年,的銷售效率指數(shù)始終大于,這說明公司在銷售與營銷上的花的每一美元都至少會收回一美元或更多的回報。 讓我們回到17年前,那天軟件服務(wù)商Siebel正在進(jìn)行其用戶會議??雌饋硪磺卸际前舶察o靜的,但是加州從來就不會一直這么安靜,因為這里有好萊塢也有硅谷。突然間,Siebel...
摘要:下圖就是第一版當(dāng)時的樣子年圍繞他們的發(fā)起了積極的營銷策略,比如像前文提到的那兩次小花招,借此向人們進(jìn)一步傳遞了的主張。從年到年,的銷售效率指數(shù)始終大于,這說明公司在銷售與營銷上的花的每一美元都至少會收回一美元或更多的回報。 讓我們回到17年前,那天軟件服務(wù)商Siebel正在進(jìn)行其用戶會議??雌饋硪磺卸际前舶察o...
摘要:繼續(xù)我們的設(shè)計模式學(xué)習(xí),有個好的觀察者可以讓你開發(fā)效率大大提高直接進(jìn)入正題,我們用一個氣象站程序來模擬此模式。內(nèi)置了觀察者模式的實現(xiàn)。 繼續(xù)我們的設(shè)計模式學(xué)習(xí),有個好的觀察者可以讓你開發(fā)效率大大提高 直接進(jìn)入正題,我們用一個氣象站程序來模擬此模式。有一個氣象站程序,能對濕度,溫度,氣壓進(jìn)行監(jiān)測并顯示在顯示裝置上面模擬圖如下,此系統(tǒng)中有三個部分氣象站:獲取實際氣象數(shù)據(jù)的裝置Weather...
閱讀 2121·2021-11-05 09:42
閱讀 2864·2021-09-23 11:21
閱讀 2862·2019-08-30 14:00
閱讀 3328·2019-08-30 13:15
閱讀 476·2019-08-29 17:18
閱讀 3565·2019-08-29 16:29
閱讀 2768·2019-08-29 14:06
閱讀 2804·2019-08-23 14:41