• 欢迎访问搞代码网站,推荐使用最新版火狐浏览器和Chrome浏览器访问本网站!
  • 如果您觉得本站非常有看点,那么赶紧使用Ctrl+D 收藏搞代码吧

Java如何利用状态模式(state pattern)替代if else

java 搞代码 4年前 (2022-01-09) 34次浏览 已收录 0个评论

大多数开发人员现在还在使用if else的过程结构,曾看过jdon的banq大哥写的一篇文章,利用command,aop模式替代if else过程结构。当时还不太明白,这几天看了《重构》第一章的影片租赁案例,感触颇深。下面我来谈一谈为什么要用state pattern替代if else,替代if else有什么好处,以

本文来源gao!%daima.com搞$代*!码9网(

及给出详细代码怎么替代if else。本文参考jdon的“你还在使用if else吗?”及《重构》第一章。

首先我们模仿影片租赁过程,顾客租凭影片,影片分为儿童片、普通片、新片。根据影片类型及租凭天数价格各不相同(优惠程度不同),用户累计积分不同。

OK ,现在我们使用 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 。


搞代码网(gaodaima.com)提供的所有资源部分来自互联网,如果有侵犯您的版权或其他权益,请说明详细缘由并提供版权或权益证明然后发送到邮箱[email protected],我们会在看到邮件的第一时间内为您处理,或直接联系QQ:872152909。本网站采用BY-NC-SA协议进行授权
转载请注明原文链接:Java如何利用状态模式(state pattern)替代if else

喜欢 (0)
[搞代码]
分享 (0)
发表我的评论
取消评论

表情 贴图 加粗 删除线 居中 斜体 签到

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址