使用state pattern怎么在Java中实现if else功能
创始人
2024-11-20 02:01:13
0次

 if else 表示。

 package com.qujingbo.movie;

 /**
 * 

Title:影片基类 *

*

Description: *

*

Date:2006-10-14 15:47:55 *

* * @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 。先来个类图。

使用state pattern怎么在Java中实现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;

/**
 * 

Title: *

*

Description: *

*

Date:2006-10-14 15:48:22 *

* * @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;

/**
 * 

Title:儿童片租赁积分、价格实现 *

*

Description: *

*

Date:2006-10-14 15:49:04 *

* * @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;

/**
 * 

Title:普通片租赁积分、价格实现 *

*

Description: *

*

Date:2006-10-14 15:50:10 *

* * @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;

/**
 * 

Title:最新发布片租赁积分、价格实现 *

*

Description: *

*

Date:2006-10-14 15:48:51 *

* * @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;

/**
 * 

Title:影片类 *

*

Description: *

*

Date:2006-10-14 15:47:55 *

* * @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;

/**
 * 

Title:自定义异常 *

*

Description: *

*

Date:2006-10-14 19:21:08 *

* * @author EOMS 曲静波 * @version 1.0 */ public class MovieException extends Exception { public MovieException(String msg) { super(msg); } }

下面模访一个顾客租赁影片。

package com.qujingbo.movie;

/**
 * 

Title: *

*

Description: *

*

Date:2006-10-14 19:26:23 *

* * @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;

 /**
 * 

Title:junit测试类 *

*

Description: *

*

Date:2006-10-14 19:32:57 *

* * @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

相关内容

热门资讯

空调连续工作多久需要停机休息 空调连续工作的时间取决于多个因素,包括空调的型号、功率、使用环境和维护情况等。一般来说,空调可以连续...
空调哪个符号是除湿的 空调除湿功能通常用一个水滴形状的符号表示。不同品牌和型号的空调遥控器可能会有所差异,但一般来说,除湿...
格力空调多长时间加一次氟利昂 1、一般情况下,空调对氟利昂的使用量是非常小的,所以在空调使用了四年左右的时候再考虑加也没问题。2、...
空调用多长时间需要加氟一次 一般情况下是五年。当出现以下这几种情况时,空调才需要加氟。1、空调的室内机和室外机各有两个接口,当接...
格调生活·C标思享荟:卡萨帝在... 9月12日的郑州龙湖金融岛,夜风轻拂,灯光璀璨。“C标时刻共传奇——卡萨帝思享荟暨20周年品牌盛典郑...
品牌价值破千亿、高端份额持续领... 9月12日,“C标时刻共传奇——卡萨帝思享荟暨20周年品牌盛典郑州站”在郑州龙湖金融岛举办。2026...
空调主板坏了修800还是换新的 空调主板坏了是修还是换新,需要考虑多个因素,以下是一些建议:1. 维修成本:如果维修费用较低,比如 ...
空调开多久需要休息多长时间 问题:空调开多久需要休息多长时间回答:1、在使用空调的过程中,一般空调开7~8个小时左右需要休息2~...
中央空调多长时间清洗一次 1、一般空调开机前清洗一次即可,空调开机中间时段再清洗一次,空调关机时清洗一次,这样比较合理。2、空...
中央空调氟利昂多久加一次 看空调制热和制冷程度,很多人的观点认为氟利昂必须一年放一次,其实这个观点是错误的,理解上面有点偏差,...