摘要:前言當代碼中出現多重語句或者語句時。代替多重分支這個情況的代替方式是可以為晴天時處理邏輯下雨時處理邏輯陰天時處理邏輯策略模式使用策略模式可以代替多重和語句,讓代碼維護變得更加簡單。狀態模式允許一個對象在其內部狀態改變的時候改變其行為。
前言
當代碼中出現多重if-else語句或者switch語句時。弊端之一:如果這樣的代碼出現在多處,那么一旦出現需求變更,就需要把所有地方的if-else或者switch代碼進行更改,要是遺漏了某一處,那么程序就會出錯。弊端之二:代碼邏輯難以理解。
衛語句衛語句的使用,并不能改變前言說的弊端:一旦需求更改,需要修改所有使用更改需求的if-else代碼塊。不過使用衛語句可以讓自己或者代碼維護人員很容易的了解代碼的含義。
代替異常分支所謂的異常分支就是普通情況之外的分支,這種情況的下的if-else可以用
if (condition) return obj;
代替。
代替多重if-else分支這個情況的代替方式是可以為
if (isSunshine()) { // 晴天時處理邏輯 } if (isRain()) { // 下雨時處理邏輯 } if (isOvercast()) { // 陰天時處理邏輯 } ...策略模式
使用策略模式可以代替多重if-else和switch語句,讓代碼維護變得更加簡單。
策略模式UML:
環境(Context)角色:持有一個Strategy的引用
抽象策略(Strategy)角色:這是一個抽象角色,通常由一個接口或抽象類實現
具體策略(ConcreteStrategy)角色:包裝了相關的算法或行為
策略模式代碼模板:
package xyz.zeling.test.strategy.template; import xyz.zeling.test.strategy.template.base.Strategy; /** * @description 環境角色 * @author zeling * @date 2018年1月14日 下午8:43:58 */ public class Context { /** * 策略對象 */ private Strategy strategy; /** * @param strategy 具體策略對象 */ public Context(Strategy strategy) { this.strategy = strategy; } /** * @description 執行策略方法 * @date 2018年1月14日 下午8:43:31 */ public void contextInterface() { strategy.strategyInterface(); } }
package xyz.zeling.test.strategy.template.base; /** * @description 抽象策略角色 * @author zeling * @date 2018年1月14日 下午8:41:14 */ public interface Strategy { /** * @description 策略方法 * @date 2018年1月14日 下午8:41:00 */ void strategyInterface(); }
package xyz.zeling.test.strategy.template; import xyz.zeling.test.strategy.template.base.Strategy; /** * @description 具體策略類A * @author zeling * @date 2018年1月14日 下午8:45:00 */ public class ConcreteStrategyA implements Strategy { @Override public void strategyInterface() { // TODO Auto-generated method stub } }
package xyz.zeling.test.strategy.template; import xyz.zeling.test.strategy.template.base.Strategy; /** * @description 具體策略類B * @author zeling * @date 2018年1月14日 下午8:45:00 */ public class ConcreteStrategyB implements Strategy { @Override public void strategyInterface() { // TODO Auto-generated method stub } }
package xyz.zeling.test.strategy.template; import xyz.zeling.test.strategy.template.base.Strategy; /** * @description 具體策略類C * @author zeling * @date 2018年1月14日 下午8:45:00 */ public class ConcreteStrategyC implements Strategy { @Override public void strategyInterface() { // TODO Auto-generated method stub } }
實例應用:水果有不同種類,每種水果對應不同價格,用策略模式實現。
package xyz.zeling.test.strategy.demo.base; /** * @description 抽象策略,水果接口 * @author zeling * @date 2018年1月14日 下午3:01:20 */ public interface Fruit { /** * @description 輸出對應價格 * @date 2018年1月14日 下午3:03:07 */ void price(); }
package xyz.zeling.test.strategy.demo; import xyz.zeling.test.strategy.demo.base.Fruit; /** * @description 具體策略,蘋果類 * @author zeling * @date 2018年1月14日 下午3:04:17 */ public class Apple implements Fruit { @Override public void price() { System.out.println("蘋果的價格!"); } }
package xyz.zeling.test.strategy.demo; import xyz.zeling.test.strategy.demo.base.Fruit; /** * @description 具體策略,香蕉 * @author zeling * @date 2018年1月14日 下午3:06:52 */ public class Banana implements Fruit { @Override public void price() { System.out.println("香蕉的價格!"); } }
package xyz.zeling.test.strategy.demo; import xyz.zeling.test.strategy.demo.base.Fruit; /** * @description 具體策略,梨 * @author zeling * @date 2018年1月14日 下午3:08:19 */ public class Pear implements Fruit { @Override public void price() { System.out.println("梨的價格!"); } }
package xyz.zeling.test.strategy.demo; import xyz.zeling.test.strategy.demo.base.Fruit; /** * @description 策略環境,輸出水果價格 * @author zeling * @date 2018年1月14日 下午3:09:31 */ public class FruitPrice { /** * 策略對象 */ private Fruit fruit; /** * @param fruit 策略對象 */ public FruitPrice(Fruit fruit) { this.fruit = fruit; } /** * @description 輸出水果價格 * @date 2018年1月14日 下午3:12:26 */ public void printFruitPrice() { fruit.price(); } }
客戶端
/** * @description 使用策略模式:針對一組算法,將每一個算法封裝到具有共同接口的獨立的類 * @date 2018年1月14日 下午3:17:11 */ public static void useStrategy() { // 具體使用策略 Fruit apple = new Apple(); // 將策略放入環境中并執行策略 new FruitPrice(apple).printFruitPrice(); }狀態模式
狀態模式類圖:
說明:
環境(Context)角色,也成上下文:定義客戶端所感興趣的接口,并且保留一個具體狀態類的實例。這個具體狀態類的實例給出此環境對象的現有狀態
抽象狀態(State)角色:定義一個接口,用以封裝環境(Context)對象的一個特定的狀態所對應的行為
具體狀態(ConcreteState)角色:每一個具體狀態類都實現了環境(Context)的一個狀態所對應的行為
策略模式代碼模板:
package xyz.zeling.test.state.template.base; /** * @description 抽象狀態角色 * @author zeling * @date 2018年1月14日 下午8:41:14 */ public interface State { /** * @description 處理方法 * @date 2018年1月14日 下午8:41:00 */ void handle(); }
package xyz.zeling.test.state.template; import xyz.zeling.test.state.template.base.State; /** * @description 具體狀態類A * @author zeling * @date 2018年1月14日 下午8:45:00 */ public class ConcreteStateA implements State { @Override public void handle() { // TODO Auto-generated method stub } }
package xyz.zeling.test.state.template; import xyz.zeling.test.state.template.base.State; /** * @description 具體狀態類A * @author zeling * @date 2018年1月14日 下午8:45:00 */ public class ConcreteStateB implements State { @Override public void handle() { // TODO Auto-generated method stub } }
package xyz.zeling.test.state.template; import xyz.zeling.test.state.template.base.State; /** * @description 具體狀態類A * @author zeling * @date 2018年1月14日 下午8:45:00 */ public class ConcreteStateC implements State { @Override public void handle() { // TODO Auto-generated method stub } }
package xyz.zeling.test.state.template; import xyz.zeling.test.state.template.base.State; /** * @description 狀態模式,環境角色類 * @author zeling * @date 2018年1月14日 下午8:43:58 */ public class Context { /** * 狀態對象 */ private State state; /** * @description 設置狀態 * @date 2018年1月14日 下午9:13:20 * @param state 具體狀態 */ public void setState(State state) { this.state = state; } /** * @description 執行策略方法 * @date 2018年1月14日 下午8:43:31 */ public void request() { state.handle(); } }
實例應用:橘子有不同顏色,狀態不同的橘子顏色不同,用狀態模式實現。
package xyz.zeling.test.state.demo.base; /** * @description 狀態模式,狀態接口 * @author zeling * @date 2018年1月14日 下午4:13:21 */ public interface Orange { /** * @description 輸出橘子的顏色 * @date 2018年1月14日 下午4:14:00 */ void printColor(); }
package xyz.zeling.test.state.demo; import xyz.zeling.test.state.demo.base.Orange; /** * @description 狀態2:青色的橘子 * @author zeling * @date 2018年1月14日 下午4:17:52 */ public class CyanOrange implements Orange { @Override public void printColor() { System.out.println("My color is cyan!"); } }
package xyz.zeling.test.state.demo; import xyz.zeling.test.state.demo.base.Orange; /** * @description 橘子狀態管理器 * @author zeling * @date 2018年1月14日 下午4:19:55 */ public class OrangeStateManage { /** * 橘子的狀態 */ private Orange state; /** * @description 設置橘子的狀態 * @date 2018年1月14日 下午4:21:36 * @param state */ public void setState(Orange state) { this.state = state; } /** * @description 輸出當前狀態的橘子顏色 * @date 2018年1月14日 下午4:22:08 */ public void print() { state.printColor(); } }
package xyz.zeling.test.state.demo; import xyz.zeling.test.state.demo.base.Orange; /** * @description 狀態1:紅色外觀的橘子 * @author zeling * @date 2018年1月14日 下午4:15:29 */ public class RedOrange implements Orange { @Override public void printColor() { System.out.println("My color is red!"); } }
package xyz.zeling.test.state.demo; import xyz.zeling.test.state.demo.base.Orange; /** * @description 狀態3:黃色的橘子 * @author zeling * @date 2018年1月14日 下午4:18:45 */ public class YellowOrange implements Orange { @Override public void printColor() { System.out.println("My color is yellow!"); } }
客戶端
/** * @description 使用狀態模式:狀態模式,又稱狀態對象模式(Pattern of Objects for * States),狀態模式是對象的行為模式。狀態模式允許一個對象在其內部狀態改變的時候改變其行為。這個對象看上去就像是改變了它的類一樣 * @date 2018年1月14日 下午4:04:16 */ public static void useState() { // 具體使用狀態 Orange cyanOrange = new CyanOrange(); // 創建環境 OrangeStateManage orangeStateManage = new OrangeStateManage(); // 設置狀態并執行 orangeStateManage.setState(cyanOrange); orangeStateManage.print(); }策略模式和狀態模式的比較
講真,我覺得它們都差不多啊,好難區別啊!!!
不過,雖然講不出來它們的區別是什么,但是有個例子可以很好的描述它們的區別
demo狀態模式:這個模式就好比員工申請離職單的流程,離職單到直接上級,這個狀態就是直接上級批示,等直接上級審閱之后,通過了就到下一個狀態。這一個個狀態對應不同的處理,這是有順序要求的。
策略模式:這個模式好比于你假期要出國游玩,有日本、美國、新加坡等國家,你每到一個國家就執行不同的游玩策略,可以先去日本,也可以先去美國,沒有順序要求。
github地址:https://github.com/zeling1005...
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/70926.html
摘要:高質量特性面向對象,無類,原型可維護的代碼可讀一致可預測看起來像是同一個人寫的文檔減少全局對象,傳參訪問全局對象單模式,忘記時的副作用顯式聲明的全局變量無法用刪除不擴充內置原型模式每個和對齊這里不考慮花括號相關的縮進規則每個中的代碼整齊縮進 高質量Javascript Javascript特性:面向對象,無類,原型 可維護的代碼(可讀;一致;可預測;看起來像是同一個人寫的;文檔) 減...
摘要:說明這篇文章是我第一次認真閱讀阿里巴巴開發手冊終極版的筆記。說明本手冊明確防止是調用者的責任。一年半載后,那么單元測試幾乎處于廢棄狀態。好的單元測試能夠最大限度地規避線上故障。 說明 這篇文章是我第一次(認真)閱讀《阿里巴巴 Java 開發手冊(終極版)》的筆記。手冊本身對規范的講解已經非常詳細了,如果你已經有一定的開發經驗并且有良好的編碼習慣和意識,會發現大部分規范是符合常識的。所以...
摘要:在重構法則上,這種叫法則,衛語句。在我們使用語句時,判斷是否是錯誤的情況出現嵌套,可以是用語句,讓失敗前置。 問題:當我們在寫業務邏輯時候,不知不覺已經把代碼嵌套了好幾次: if (true){ if (true){ if (true){ for (){ ...
那有什么天生如此,只是我們天天堅持。 本篇文章主要講解 《重構---改善既有代碼的設計》 這本書中的 第九章簡化條件表達式中 的知識點, Decompose Conditional(分解條件表達式) 問題:你有一個復雜的條件(if、then、else) 語句 解決:從if、then、else三個段落中分別提煉出獨立函數 //重構前 if (date.before(SUMMER_START) |...
閱讀 3738·2021-10-15 09:42
閱讀 2600·2021-09-03 10:50
閱讀 1632·2021-09-03 10:28
閱讀 1793·2019-08-30 15:54
閱讀 2515·2019-08-30 12:46
閱讀 409·2019-08-30 11:06
閱讀 2824·2019-08-30 10:54
閱讀 527·2019-08-29 12:59