使用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功能的方法了吗?如果还想学到更多技能或想了解更多相关内容,欢迎关注亿速云行业资讯频道,感谢各位的阅读!
亿速云「云服务器」,即开即用、新一代英特尔至强铂金CPU、三副本存储NVMe SSD云盘,价格低至29元/月。点击查看>>
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。