久久福利_99r_国产日韩在线视频_直接看av的网站_中文欧美日韩_久久一

您的位置:首頁技術(shù)文章
文章詳情頁

Java如何利用狀態(tài)模式(state pattern)替代if else

瀏覽:16日期:2022-08-20 18:23:51

大多數(shù)開發(fā)人員現(xiàn)在還在使用if else的過程結(jié)構(gòu),曾看過jdon的banq大哥寫的一篇文章,利用command,aop模式替代if else過程結(jié)構(gòu)。當時還不太明白,這幾天看了《重構(gòu)》第一章的影片租賃案例,感觸頗深。下面我來談一談為什么要用state pattern替代if else,替代if else有什么好處,以及給出詳細代碼怎么替代if else。本文參考jdon的“你還在使用if else嗎?”及《重構(gòu)》第一章。

首先我們模仿影片租賃過程,顧客租憑影片,影片分為兒童片、普通片、新片。根據(jù)影片類型及租憑天數(shù)價格各不相同(優(yōu)惠程度不同),用戶累計積分不同。

OK ,現(xiàn)在我們使用 if else 表示。

package com.qujingbo.movie; /** * <p/> Title:影片基類 * </p> * <p/> Description: * </p> * <p/> Date:2006-10-14 15:47:55 * </p> * * @author EOMS 曲靜波 * @version 1.0 */ public class Movie { // 普通片標識 public static int REGULAR = 1 ; // 新片標識 public static int NEW_RELEASE = 2 ; // 兒童片標識 public static int CHILDREN = 3 ; /** * 獲取租賃影片總價 * * @param movieCode * 影片類型 * @param days * 租憑天數(shù) * @return 租賃影片總價 * @throws MovieException * 沒有影片類型拋出異常 */ public double getCharge( int movieCode, int days) throws MovieException { double result = 0 ; // 普通片 if (movieCode == Movie.REGULAR) // 單價為2 { result = 2 ; // 如果租賃天數(shù)大于2則,則優(yōu)惠 if (days > 2 ) { result += (days - 2 ) * 1.5 ; } // 返回總價 return result; } // 最新發(fā)布片 else if (movieCode == Movie.NEW_RELEASE) { // 新片沒有優(yōu)惠,單價為3 return days * 3 ; } // 兒童片 else if (movieCode == Movie.CHILDREN) { // 影片單價 result = 1.5 ; // 如果租賃時間大于3天則做價格優(yōu)惠 if (days > 3 ) { result += (days - 3 ) * 1.5 ; } // 返回租賃影片總價 return result; } else throw new MovieException( ' 影片不存在 ' ); } /** * 獲取租賃影片積分 * * @param movieCode * 影片類型 * @param days * 租憑天數(shù) * @return 租賃影片積分 * @throws MovieException * 沒有影片類型拋出異常 */ public double getIntegral( int movieCode, int days) throws MovieException { // 普通片 if (movieCode == Movie.REGULAR) return days * 2 ; // 最新發(fā)布片 else if (movieCode == Movie.NEW_RELEASE) return days * 3 ; // 兒童片 else if (movieCode == Movie.CHILDREN) return days * 1.5 ; else throw new MovieException( ' 影片不存在 ' ); }}

OK ,我們看一下,現(xiàn)在的 Movie 完全符合租賃需求,通過 getIntegral(int movieCode,int days) 和 getCharge(int movieCode,int days) 來獲得租賃積分及租賃價格。從開閉原則角度來看,如果要添加新的影片類型,我們必須修改 getIntegral(int movieCode,int days) 和 getCharge(int movieCode,int days) 這兩個方法。而若要改變租賃價格、積分的優(yōu)惠規(guī)則時,仍需要修改 getIntegral(int movieCode,int days) 和 getCharge(int movieCode,int days) 方法。現(xiàn)在看來,只有三種影片類型,維護還較方便。而當影片類型較多時,例如 10 種, 100 種影片類型,這樣就是不可以想像的維護。

現(xiàn)在我們來看一下,使用 state pattern 來代替 if else 。先來個類圖。

Java如何利用狀態(tài)模式(state pattern)替代if else

首先我們建立一個 abstract class Price 做為影片類型的基類,基類中含有兩個 abstract 方法,獲取總價格 getCharge(int days), 獲取總積分 getIntegral(int days) 方法 , 繼承 abstract classPrice 的三個影片類型兒童片 class ChilerenPrice, 普通片 class RegularPrice, 最新片 class NewReleasePrice 。分別實現(xiàn) getCharge(int days),getIntegral(int days) 方法,實現(xiàn)方法寫入計算價格的優(yōu)惠方案及積分的方案。當需要修改方案時,我們只需在某個影片類的方法中對應(yīng)修改就可以。若新增一個影片分類時,我們只需新增一個實現(xiàn)類實現(xiàn) abstract class Price 類就 OK 。

class Movie 代表影片,其關(guān)聯(lián)一個 Price 類,而 setPrice(String movieClass) 方法類似于一個工廠類,傳入 movieClass 為包名類名,用 java 反射機制實例化一個具體傳入 movieClass 的影片類型實現(xiàn)類,這樣我們通過這幾行代碼就可以獲得該影片類型的價格和積分。

Movie regularMovie = new Movie();regularMovie.setPrice(Movie.REGULAR);System.out.println( ' 普通影片租賃10天的價格 ' + regularMovie.getPrice().getCharge( 10 ));System.out.println( ' 普通影片租賃10天的積分 ' + regularMovie.getPrice().getIntegral( 10 ));

下面我們給出詳細代碼

abstract class Price價格基類

package com.qujingbo.movie;/** * <p/> Title: * </p> * <p/> Description: * </p> * <p/> Date:2006-10-14 15:48:22 * </p> * * @author EOMS 曲靜波 * @version 1.0 */public abstract class Price { /** * 獲取租賃影片價格需實現(xiàn)該此方法 * * @param days * 租賃天數(shù) * @return 返回影片價格 */ public abstract double getCharge(int days); /** * 獲取租賃影片積分需實現(xiàn)此方法 * * @param days * 租賃天數(shù) * @return 返回影片積分 */ public abstract double getIntegral(int days);}

兒童片ChildrenPrice類,實現(xiàn)abstract class Price ,實現(xiàn)兒童片租賃總價getCharge(int days)及兒童片租賃積分getIntegral(int days)。

package com.qujingbo.movie;/** * <p/> Title:兒童片租賃積分、價格實現(xiàn) * </p> * <p/> Description: * </p> * <p/> Date:2006-10-14 15:49:04 * </p> * * @author EOMS 曲靜波 * @version 1.0 */public class ChildrenPrice extends Price { /** * 兒童片返回租賃積分,兒童片積分規(guī)則為: 根據(jù) */ public double getIntegral(int days) { // 返回租賃影片積分 return days * 1.5; } /** * 兒童片返回租賃價格 */ public double getCharge(int days) { // 影片單價 double result = 1.5; // 如果租賃時間大于3天則做價格優(yōu)惠 if (days > 3) { result += (days - 3) * 1.5; } // 返回租賃影片總價 return result; }}

普通片RegularlPrice類,實現(xiàn)abstract class Price ,實現(xiàn)普通片租賃總價getCharge(int days)及普通片租賃積分getIntegral(int days)。

package com.qujingbo.movie;/** * <p/> Title:普通片租賃積分、價格實現(xiàn) * </p> * <p/> Description: * </p> * <p/> Date:2006-10-14 15:50:10 * </p> * * @author EOMS 曲靜波 * @version 1.0 */public class RegularlPrice extends Price { /** * 普通片返回租賃積分,普通片積分規(guī)則 */ public double getIntegral(int days) { // 返回租賃影片積分 return days * 2; } /** * 普通片返回租賃價格 */ public double getCharge(int days) { // 單價為2 double result = 2; // 如果租賃天數(shù)大于2則,則優(yōu)惠 if (days > 2) { result += (days - 2) * 1.5; } // 返回總價 return result; }}

最新發(fā)布片NewReleasePrice類,實現(xiàn)abstract class Price ,實現(xiàn)最新發(fā)布片租賃總價getCharge(int days)及最新發(fā)布片租賃積分getIntegral(int days)。

package com.qujingbo.movie;/** * <p/> Title:最新發(fā)布片租賃積分、價格實現(xiàn) * </p> * <p/> Description: * </p> * <p/> Date:2006-10-14 15:48:51 * </p> * * @author EOMS 曲靜波 * @version 1.0 */public class NewReleasePrice extends Price { /** * 最新發(fā)布片返回租賃積分,最新發(fā)布片積分規(guī)則 */ public double getIntegral(int days) { // 返回租賃影片積分 return days * 3; } /** * 最新發(fā)布片返回租賃價格 */ public double getCharge(int days) { // 新片沒有優(yōu)惠,單價為3 return days * 3; }}

電影Movie類,setPrice(String movieClass)(工廠)方法,通過java反射機制實現(xiàn)movieClass(包名,類名)類。若沒有movieClass這個類,則拋出MovieException異常。

package com.qujingbo.movie;/** * <p/> Title:影片類 * </p> * <p/> Description: * </p> * <p/> Date:2006-10-14 15:47:55 * </p> * * @author EOMS 曲靜波 * @version 1.0 */public class Movie { // 普通片標識 public static String REGULAR = 'com.qujingbo.movie.RegularlPrice'; // 新片標識 public static String NEW_RELEASE = 'com.qujingbo.movie.NewReleasePrice'; // 兒童片標識 public static String CHILDREN = 'com.qujingbo.movie.ChildrenPrice'; private Price price; public Price getPrice() { return price; } /** * 確定返回具體某個影片類型的實現(xiàn)類,有點像工廠 * * @param movieCode * 影片類型 * @throws MovieException * 若無影片類型則拋異常。 */ public void setPrice(String movieClass) throws MovieException { try { Class cls = Class.forName(movieClass); this.price = (Price) cls.newInstance(); } catch (Exception e) { throw new MovieException('影片不存在'); } }}

給出MovieException源碼。

package com.qujingbo.movie;/** * <p/> Title:自定義異常 * </p> * <p/> Description: * </p> * <p/> Date:2006-10-14 19:21:08 * </p> * * @author EOMS 曲靜波 * @version 1.0 */public class MovieException extends Exception { public MovieException(String msg) { super(msg); }}

下面模訪一個顧客租賃影片。

package com.qujingbo.movie;/** * <p/> Title: * </p> * <p/> Description: * </p> * <p/> Date:2006-10-14 19:26:23 * </p> * * @author EOMS 曲靜波 * @version 1.0 */public class Customer { /** * 消費(測試程序) * * @throws MovieException * 若沒有影片,拋出異常 */ public void consume() throws MovieException { // 普通電影 Movie regularMovie = new Movie(); regularMovie.setPrice(Movie.REGULAR); // 最新發(fā)布電影 Movie newReleaseMovie = new Movie(); newReleaseMovie.setPrice(Movie.NEW_RELEASE); // 兒童電影 Movie childrenMovie = new Movie(); childrenMovie.setPrice(Movie.CHILDREN); System.out.println('普通影片租賃10天的價格' + regularMovie.getPrice().getCharge(10)); System.out.println('最新影片租賃10天的價格' + newReleaseMovie.getPrice().getCharge(10)); System.out.println('兒童影片租賃10天的價格' + childrenMovie.getPrice().getCharge(10)); System.out.println('普通影片租賃10天的積分' + regularMovie.getPrice().getIntegral(10)); System.out.println('最新影片租賃10天的積分' + newReleaseMovie.getPrice().getIntegral(10)); System.out.println('兒童影片租賃10天的積分' + childrenMovie.getPrice().getIntegral(10)); }}

寫一 junit 測試類運行 class Customer 的 consume() 方法。

package com.qujingbo.movie; import junit.framework.TestCase; /** * <p/> Title:junit測試類 * </p> * <p/> Description: * </p> * <p/> Date:2006-10-14 19:32:57 * </p> * * @author EOMS 曲靜波 * @version 1.0 */ public class CustomerTest extends TestCase { private Customer customer = null ; protected void setUp() throws Exception { super .setUp(); customer = new Customer(); } protected void tearDown() throws Exception { super .tearDown(); } /* * Test method for ’com.qujingbo.movie.Customer.consume()’ */ public void testConsume() { try { customer.consume(); } catch (MovieException e) { System.out.println( ' 沒有該類影片 ' ); } }}

OK 。結(jié)果為:

普通影片租賃 10 天的價格 14.0

最新影片租賃 10 天的價格 30.0

兒童影片租賃 10 天的價格 12.0

普通影片租賃 10 天的積分 20.0

最新影片租賃 10 天的積分 30.0

兒童影片租賃 10 天的積分 15.0

最后我要說,我們用 OO 表示的租賃過程并不完整,因為顧客不一定只租賃一部影片,而要租賃多部影片,這樣我們?nèi)鄙僖粋€ Rental (租賃類)。而只是為說明 state pattern 替代 if else ,所以我們沒有添加 Rental (租賃類),若需要參考,請查閱《重構(gòu)》第一章。 點擊下載源碼.

到此這篇關(guān)于Java如何利用狀態(tài)模式(state pattern)替代if else的文章就介紹到這了,更多相關(guān)Java用狀態(tài)模式(state pattern)替代if else內(nèi)容請搜索好吧啦網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持好吧啦網(wǎng)!

標簽: Java
相關(guān)文章:
主站蜘蛛池模板: 欧美日韩不卡合集视频 | 蜜桃视频在线观看www社区 | 日韩在线观看中文字幕 | 久久精品欧美 | ririsao亚洲国产中文 | 国产欧美一区二区三区在线看 | 黄色免费一级 | 国产一级影片 | 国产 一区 | 久久久久久久久久国产精品 | 精品亚洲成a人在线观看 | a级片在线观看 | 日本a在线| 欧美激情综合五月色丁香小说 | a久久| 欧美综合久久久 | 亚洲激情综合 | 亚洲国产精品久久久久久女王 | 色免费视频 | 久久国产精品91 | 国产美女自拍视频 | 欧美a在线 | 亚洲成人久久久 | 国产高清在线精品一区二区三区 | 中文字幕视频在线观看 | 成年人视频在线观看免费 | www.日韩系列| 国产91久久久久 | 91视频免费看 | 国产综合亚洲精品一区二 | 精品亚洲视频在线观看 | 中文字幕av一区二区 | 欧美日韩精品一区二区在线播放 | 国产精品久久久爽爽爽麻豆色哟哟 | 成人黄页在线观看 | 国产1级片| 欧美激情一区二区 | 日本在线一二 | 成人午夜剧场 | 久久毛片 | 在线成人 |