最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

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

 更新時間:2020年11月19日 15:50:31   作者:xzc  
這篇文章主要給大家介紹了關于Java如何利用狀態(tài)模式(state pattern)替代if else的相關資料,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧

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

首先我們模仿影片租賃過程,顧客租憑影片,影片分為兒童片、普通片、新片。根據(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 。先來個類圖。

首先我們建立一個 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)惠方案及積分的方案。當需要修改方案時,我們只需在某個影片類的方法中對應修改就可以。若新增一個影片分類時,我們只需新增一個實現(xiàn)類實現(xiàn) abstract class Price 類就 OK 。

class Movie 代表影片,其關聯(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 。結果為:

普通影片租賃 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 (租賃類),若需要參考,請查閱《重構》第一章。 點擊下載源碼.

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

相關文章

  • Java實現(xiàn)讀取csv文件的兩種方式

    Java實現(xiàn)讀取csv文件的兩種方式

    這篇文章主要為大家詳細介紹了如何利用Java讀取csv文件的兩種方式,文中的示例代碼講解詳細,對大家的學習或工作有一定的幫助,感興趣的小伙伴可以了解一下
    2023-12-12
  • SpringBoot項目使用aop案例詳解

    SpringBoot項目使用aop案例詳解

    這篇文章主要介紹了SpringBoot項目使用aop的相關知識,本文給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2023-04-04
  • Java如何使用multipartFile對象解析Execl

    Java如何使用multipartFile對象解析Execl

    本文介紹了如何使用Spring的MultipartFile類解析Excel文件(.xls和.xlsx),包括文件上傳、數(shù)據(jù)校驗、輸入流獲取、文件解析、數(shù)據(jù)保存和異常處理的詳細步驟
    2025-02-02
  • Java接入DeepSeek的保姆級教程(適合新手)

    Java接入DeepSeek的保姆級教程(適合新手)

    對于目前的DeepSeek大家應該都不是很陌生,目前也是最流行的一款AI軟件了,所以為了讓我們開發(fā)更全面,能夠在自己的項目中融入AI那就會很全面了,所以這次的文章,將模擬一個基礎案例,可以在這個基礎案例迭代實現(xiàn)出你自己的AI,需要的朋友可以參考下
    2025-02-02
  • SpringBoot全局處理統(tǒng)一返回類型方式

    SpringBoot全局處理統(tǒng)一返回類型方式

    這篇文章主要介紹了SpringBoot全局處理統(tǒng)一返回類型方式,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2023-07-07
  • Spring中@Cacheable注解的使用詳解

    Spring中@Cacheable注解的使用詳解

    這篇文章主要介紹了Spring中@Cacheable注解的使用詳解,Spring框架提供了@Cacheable注解來輕松地將方法結果緩存起來,以便在后續(xù)調用中快速訪問,本文將詳細介紹@Cacheable注解的使用方法,并從源碼級別解析其實現(xiàn)原理,需要的朋友可以參考下
    2023-11-11
  • java連接mysql數(shù)據(jù)庫實現(xiàn)單條插入和批量插入

    java連接mysql數(shù)據(jù)庫實現(xiàn)單條插入和批量插入

    這篇文章主要為大家詳細介紹了java連接mysql數(shù)據(jù)庫實現(xiàn)單條插入和批量插入,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2019-08-08
  • 詳解Spring Boot配置文件之多環(huán)境配置

    詳解Spring Boot配置文件之多環(huán)境配置

    本篇文章主要介紹了詳解Spring Boot配置文件之多環(huán)境配置 ,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-09-09
  • java?安全?ysoserial?CommonsCollections6?分析

    java?安全?ysoserial?CommonsCollections6?分析

    這篇文章主要介紹了java?安全?ysoserial?CommonsCollections6示例分析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2022-10-10
  • 解決nacos項目啟動報錯:Connection refused: no further informa問題

    解決nacos項目啟動報錯:Connection refused: no further&

    這篇文章主要介紹了解決nacos項目啟動報錯:Connection refused: no further informa問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2023-04-04

最新評論

海安县| 巩义市| 鹤岗市| 抚州市| 山阳县| 绥江县| 鲁甸县| 佛山市| 姜堰市| 桃源县| 平果县| 南投县| 沐川县| 西乌| 东源县| 巴彦县| 辛集市| 雷山县| 沭阳县| 华容县| 科技| 友谊县| 合江县| 古丈县| 浮山县| 夏邑县| 泊头市| 璧山县| 盈江县| 昭苏县| 崇义县| 阿克陶县| 仪征市| 内黄县| 洛南县| 万宁市| 凤山县| 文山县| 福海县| 青川县| 马尔康县|