摘要:引言要分析設計模式中的策略模式,我們可以以希伯來圣經中的一個故事為例。策略模式原理及益處這個策略依然有一個父類相當于一個模板,所有的人類子類都繼承這個父類根據這個模板來創建。
引言
要分析設計模式中的“策略模式”,我們可以以《希伯來圣經》中的一個故事為例。
《希伯來圣經》中有這樣一個故事,說的是人類產生不同語言的起源。在這個故事中,一群只說一種語言的人在“大洪水”之后從東方來到了示拿地區,并決定在這修建一座城市和一座“能夠通天的”高塔;上帝見此情形就把他們的語言打亂,讓他們再也不能明白對方的意思,并把他們分散到了世界各地。
這里我們可以將God視作一個程序員。
在他的設計中,所有的人類(Human),雖然有很多個個體,但一開始都是一樣的,說的是一樣的語言。
所以我們可以將Human類作為父類,然后所有的人類個體對象都繼承這個Human父類。父類中有一個speak()方法,所有繼承Human類的子類都將繼承這個方法,于是都擁有了用語言交流的能力。
//Human父類 public class Human { public void speak(){ System.out.println("只要是人類的子類都speak the same language"); } }
可以有很多的人類種類繼承這個Human父類,比如來自東方的的人:
public class PeopleFromEast extends { //PeopleFromEast繼承了Human, //所以也就繼承了Human父類中的speak()方法 //所以PeopleFromEast類中甚至都不需要寫任何方法 }
在demo測試中,我們可以看到,PeopleFromEast類的對象,可以調用從父類繼承來的speak()方法:
public class RunDemo { public static void main (String[] args){ //創建一個PeopleFromEast對象 PeopleFromEast peopleFromEast = new PeopleFromEast(); //讓這個對象調用從父類繼承來的方法speak() peopleFromEast.speak(); } }
根據God最初的設想,這樣的設計是沒有問題的。
“土方法”的缺陷可是后來由于語言一致,人類同心協力修建巴比塔,(程序猿)God感到受到了威脅。于是決定做出改變:讓來自不同地方的人speak不同的language——比如PeopleFromEast說EastLanguage,PeopleFromWest說WestLanguage,等等。
God要實現這樣的改變,最直觀的方法自然是讓每個繼承Human父類的人類子類重寫父類的speak()方法。
//新的PeopleFromEast類 //這一次PeopleFromEast重寫了speak()方法 public class PeopleFromEast extends Human { @Override public void speak() { System.out.println("PeopleFromEast從今以后只能speak EastLanguage"); } }
demo的運行結果:
如果人類的子類種類不多,那么(程序猿God)還可以每次都重寫Human子類的speak()方法。可是如果人類的子類有很多種呢?又或者不止speak()方法有這種情況呢?比如,也許God以后希望讓每種人類子類的行走方式都不一樣。那是不是應該在Human父類中加入一個walk()方法,然后讓每個子類都重寫呢?
也就是說,如果人類子類的“規格”常常改變,每當有新的人類子類出現,(程序猿)God都要被迫檢查并可能需要覆蓋speak()和walk(),這絕對是God所不愿意看見的。
策略模式原理及益處這個策略依然有一個Human父類(相當于一個模板),所有的人類子類都繼承這個父類(根據這個模板來創建)。
所不同的是,這次God決定在每個人類的子類中都附上自己的一份意識。讓這份意識來控制這個子類應該說的語言種類。為了方便敘述,我們可以將God的這一意識稱為LanguageController。
然后,God為人類的子類可以說的Language種類提供了一個選擇范圍。
比如,中國人(ChineseMan--因為Chinese既可以表示“中文”又可以表示“中國人”,為了區分,我們稱“中國人”為"ChineseMan")說中文(Chinese),美國人(American)就說英文(English)。
這樣一來,在每個人類子類創建時,God附在其上的意識LanguageController將發揮作用,然后按照God的意愿,從language的可選范圍中選擇一種語言來指定給該人類子類。
這一策略在程序設計中可以這樣實現:
創建一個Human父類:
public class Human { //LanguageController是接口類型 //languageController作為Human類的field, //代表God將自己的意識附在人類父類之上, //也就代表God的意識將附在所有的人類個體之上 LanguageController languageController ; //根據God的設計,人類的模板中只需要作出規定:人會說某種語言 //而不需要作出具體的安排 public void performSpeaking (){ //人說話的時候,還得上帝的意識起作用, //決定這個“具體的人”該說何種語言 languageController.speak(); } }
創建LanguageController接口:
//創造God的意識,也就是LanguageController: public interface LanguageController { //接口中只定義了一個speak()方法 public void speak(); }
現在God要創造中國人和美國人:
ChineseMan類:
public class ChineseMan extends Human { //中國人對象的構造器 ChineseMan() { //構造ChineseMan對象時,God的意識發揮作用 //languageController是從Human父類繼承來的 //根據God的安排,要創建ChineseMan對象,就應該告訴languageController現在要創造的這個對象說中文 languageController = new speakChinese(); //在這里,由于多態的緣故,表現為具體子類--也就是speakChinese對象 skinColorController = new ColorIsLikeAsian(); } }
American類:
public class American extends Human { //American的構造器 public American (){ languageController = new SpeakEnglish(); } }
那么這個speakChinese類和speakEnglish類有什么玄機呢?
speakChinese類:
//speakChinese類實現了LanguageController接口 public class speakChinese implements LanguageController{ //實現LanguageController接口中規定的speak()方法 @Override public void speak() { System.out.println("我說中文!"); } }
speakChinese類可能不太好理解,因為speak Chinese(說中文)更多算是一種行為(action),這里卻定義為類。其實只需要換一種思維,把speakChinese類視作一種標簽,把這個標簽賦給God的意識(languageContronller),也就實現了根據不同的human子類來確定不同的語言。
speakEnglish類:
//SpeakEnglish類實現了LanguageController接口 public class SpeakEnglish implements LanguageController { @Override public void speak() { System.out.println("I speak English!"); } }
下面運行一個demo--StrategyModeDemo.java:
public class StrategyModeDemo { public static void main(String[] args){ //新建一個ChineseMan對象 Human chineseMan = new ChineseMan(); //ChineseMan說的語言: chineseMan.performSpeaking(); //American對象: Human american = new American(); //American說的語言: american.performSpeaking(); } }
StrategyModeDemo.java運行結果:
執行邏輯圖示而整個執行流程的邏輯則如圖所示:
更上一層樓當然,以上所有的Human子類在被創建時,他們說什么話就已經注定了。
這是因為他們的God的意識起作用的環節在他們的構造器中。
那么God有沒有辦法讓已經被造出來的ChineseMan對象改說English呢?
答案是肯定的!
我們只需要在Human.java中加入一個修改語言的方法即可:
public class Human { LanguageController languageController ; SkinColorController skinColorController; //控制Human的子類說的語言,比如中國人說中文 public void performSpeaking (){ languageController.speak(); } //隨時改變能說的語言 public void setLanguage (LanguageController languageController){ languageController.speak(); } }
再次運行StrategyModeDemo.java:
public class StrategyModeDemo { public static void main(String[] args){ //新建一個ChineseMan對象 Human chineseMan = new ChineseMan(); //ChineseMan說的語言: chineseMan.performSpeaking(); System.out.println("God決定讓ChineseMan也說英文"); chineseMan.setLanguage(new SpeakEnglish()); } }
個人淺見,如有不足,歡迎批評指正:)
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/74616.html
摘要:可以使用其他模式來修正這個缺陷,如工廠方法模式代理模式或享元模式。我們的策略模式只是實現了策略的管理,但是沒有嚴格地定義適當的場景使用適當的策略,在實際項目中,一般通過工廠方法模式來實現策略類的聲明。源碼地址參考文獻設計模式之禪 定義 Define a family of algorithms,encapsulate each one,and make them interchange...
摘要:一定義定義維基百科策略模式作爲一種軟件設計模式,指對象有某個行爲,但是在不同的場景中,該行爲有不同的實現算法。二策略模式圖我們看看策略模式是有怎樣設計結構的。如中創建線程池,線程池任務滿時,對提交的任務做處理就使用了策略模式。以前完整的看過《大話設計模式》,雖然完整看過,也做過筆記,但現在依然很多已經很模糊。這段時間趁著離職,有時間,打算重新過一遍,該篇將介紹策略模式。一、定義定義(維基百科...
摘要:孫臏心里一萬個草泥馬在奔騰,差點沒噎死自己滾一邊去,我們這盤跟他賽馬開始,策略模式上場。在設計模式之禪中的提出通過策略枚舉和反射機制對策略模式進行改良,膜拜了但是要添加或淘汰策略,還是得去對枚舉進行修改,也不符合開閉原則。 今天給大家說說田忌賽馬的故事。如有雷同,純屬巧合!話說在戰國時期,群雄割據,硝煙四起,茶余飯后還是少不了娛樂活動的,其中賽馬是最火爆的。一天,孫臏看到田忌像個死雞似...
閱讀 2676·2023-04-25 20:19
閱讀 1930·2021-11-24 09:38
閱讀 1632·2021-11-16 11:44
閱讀 4341·2021-09-02 15:40
閱讀 1317·2019-08-30 15:55
閱讀 2022·2019-08-30 15:52
閱讀 3759·2019-08-29 17:20
閱讀 2247·2019-08-29 13:48