您好,登錄后才能下訂單哦!
使用state pattern怎么在Java中實現if else功能?相信很多沒有經驗的人對此束手無策,為此本文總結了問題出現的原因和解決方法,通過這篇文章希望你能解決這個問題。
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 * 租憑天數 * @return 租賃影片總價 * @throws MovieException * 沒有影片類型拋出異常 */ public double getCharge( int movieCode, int days) throws MovieException { double result = 0 ; // 普通片 if (movieCode == Movie.REGULAR) // 單價為2 { result = 2 ; // 如果租賃天數大于2則,則優惠 if (days > 2 ) { result += (days - 2 ) * 1.5 ; } // 返回總價 return result; } // 最新發布片 else if (movieCode == Movie.NEW_RELEASE) { // 新片沒有優惠,單價為3 return days * 3 ; } // 兒童片 else if (movieCode == Movie.CHILDREN) { // 影片單價 result = 1.5 ; // 如果租賃時間大于3天則做價格優惠 if (days > 3 ) { result += (days - 3 ) * 1.5 ; } // 返回租賃影片總價 return result; } else throw new MovieException( " 影片不存在 " ); } /** * 獲取租賃影片積分 * * @param movieCode * 影片類型 * @param days * 租憑天數 * @return 租賃影片積分 * @throws MovieException * 沒有影片類型拋出異常 */ public double getIntegral( int movieCode, int days) throws MovieException { // 普通片 if (movieCode == Movie.REGULAR) return days * 2 ; // 最新發布片 else if (movieCode == Movie.NEW_RELEASE) return days * 3 ; // 兒童片 else if (movieCode == Movie.CHILDREN) return days * 1.5 ; else throw new MovieException( " 影片不存在 " ); } }
OK ,我們看一下,現在的 Movie 完全符合租賃需求,通過 getIntegral(int movieCode,int days) 和 getCharge(int movieCode,int days) 來獲得租賃積分及租賃價格。從開閉原則角度來看,如果要添加新的影片類型,我們必須修改 getIntegral(int movieCode,int days) 和 getCharge(int movieCode,int days) 這兩個方法。而若要改變租賃價格、積分的優惠規則時,仍需要修改 getIntegral(int movieCode,int days) 和 getCharge(int movieCode,int days) 方法。現在看來,只有三種影片類型,維護還較方便。而當影片類型較多時,例如 10 種, 100 種影片類型,這樣就是不可以想像的維護。
現在我們來看一下,使用 state pattern 來代替 if else 。先來個類圖。
首先我們建立一個 abstract class Price 做為影片類型的基類,基類中含有兩個 abstract 方法,獲取總價格 getCharge(int days), 獲取總積分 getIntegral(int days) 方法 , 繼承 abstract classPrice 的三個影片類型兒童片 class ChilerenPrice, 普通片 class RegularPrice, 最新片 class NewReleasePrice 。分別實現 getCharge(int days),getIntegral(int days) 方法,實現方法寫入計算價格的優惠方案及積分的方案。當需要修改方案時,我們只需在某個影片類的方法中對應修改就可以。若新增一個影片分類時,我們只需新增一個實現類實現 abstract class Price 類就 OK 。
class Movie 代表影片,其關聯一個 Price 類,而 setPrice(String movieClass) 方法類似于一個工廠類,傳入 movieClass 為包名類名,用 java 反射機制實例化一個具體傳入 movieClass 的影片類型實現類,這樣我們通過這幾行代碼就可以獲得該影片類型的價格和積分。
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 { /** * 獲取租賃影片價格需實現該此方法 * * @param days * 租賃天數 * @return 返回影片價格 */ public abstract double getCharge(int days); /** * 獲取租賃影片積分需實現此方法 * * @param days * 租賃天數 * @return 返回影片積分 */ public abstract double getIntegral(int days); }
兒童片ChildrenPrice類,實現abstract class Price ,實現兒童片租賃總價getCharge(int days)及兒童片租賃積分getIntegral(int days)。
package com.qujingbo.movie; /** * <p/> Title:兒童片租賃積分、價格實現 * </p> * <p/> Description: * </p> * <p/> Date:2006-10-14 15:49:04 * </p> * * @author EOMS 曲靜波 * @version 1.0 */ public class ChildrenPrice extends Price { /** * 兒童片返回租賃積分,兒童片積分規則為: 根據 */ public double getIntegral(int days) { // 返回租賃影片積分 return days * 1.5; } /** * 兒童片返回租賃價格 */ public double getCharge(int days) { // 影片單價 double result = 1.5; // 如果租賃時間大于3天則做價格優惠 if (days > 3) { result += (days - 3) * 1.5; } // 返回租賃影片總價 return result; } }
普通片RegularlPrice類,實現abstract class Price ,實現普通片租賃總價getCharge(int days)及普通片租賃積分getIntegral(int days)。
package com.qujingbo.movie; /** * <p/> Title:普通片租賃積分、價格實現 * </p> * <p/> Description: * </p> * <p/> Date:2006-10-14 15:50:10 * </p> * * @author EOMS 曲靜波 * @version 1.0 */ public class RegularlPrice extends Price { /** * 普通片返回租賃積分,普通片積分規則 */ public double getIntegral(int days) { // 返回租賃影片積分 return days * 2; } /** * 普通片返回租賃價格 */ public double getCharge(int days) { // 單價為2 double result = 2; // 如果租賃天數大于2則,則優惠 if (days > 2) { result += (days - 2) * 1.5; } // 返回總價 return result; } }
最新發布片NewReleasePrice類,實現abstract class Price ,實現最新發布片租賃總價getCharge(int days)及最新發布片租賃積分getIntegral(int days)。
package com.qujingbo.movie; /** * <p/> Title:最新發布片租賃積分、價格實現 * </p> * <p/> Description: * </p> * <p/> Date:2006-10-14 15:48:51 * </p> * * @author EOMS 曲靜波 * @version 1.0 */ public class NewReleasePrice extends Price { /** * 最新發布片返回租賃積分,最新發布片積分規則 */ public double getIntegral(int days) { // 返回租賃影片積分 return days * 3; } /** * 最新發布片返回租賃價格 */ public double getCharge(int days) { // 新片沒有優惠,單價為3 return days * 3; } }
電影Movie類,setPrice(String movieClass)(工廠)方法,通過java反射機制實現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; } /** * 確定返回具體某個影片類型的實現類,有點像工廠 * * @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); // 最新發布電影 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 。結果為:
普通影片租賃 10 天的價格 14.0
最新影片租賃 10 天的價格 30.0
兒童影片租賃 10 天的價格 12.0
普通影片租賃 10 天的積分 20.0
最新影片租賃 10 天的積分 30.0
兒童影片租賃 10 天的積分 15.0
看完上述內容,你們掌握使用state pattern怎么在Java中實現if else功能的方法了嗎?如果還想學到更多技能或想了解更多相關內容,歡迎關注億速云行業資訊頻道,感謝各位的閱讀!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。