最近在工作中优化了一段冗余的if else代码块,感觉对设计模式的理解和运用很有帮助,所以分享出来。鉴于原代码会涉及到公司的隐私,因此就不贴出来了。下面以更加通俗易懂的案例来解析。

假如写一个针对员工上班不遵守制度做相应惩罚的程序,比如,上班迟到:罚100;上班睡觉:罚1000;上班早退:警告;上班玩游戏:严重警告;上班谈恋爱:开除等,通常都会这样写:

public class WorkPunish {
public static void main(String[] agrs){
String state ="late";
punish(state);
} public static void punish(String state){
if ("late".equals(state)){
System.out.println("罚100");
}else if ("sleep".equals(state)){
System.out.println("罚1000");
}else if ("early".equals(state)){
System.out.println("警告");
}else if ("play".equals(state)){
System.out.println("严重警告");
}else if ("love".equals(state)){
System.out.println("开除");
}
}
}

可以看到,每增加一种情况都要增加一个if else判断,这样会造成这段代码非常长,可读性差、不易维护。下面就用静态工厂+策略模式来重构这段代码(对于静态工厂模式和策略模式不知道的同学请自行百度哈

先说说思路:1、定义一个处罚的接口 ,包含一个执行处罚的方法

      2、每一种情况的处罚都抽象成一个具体处罚类并继承处罚接口(策略模式)

      3、定义一个静态工厂类,用来根据情况生产具体处罚对象,然后执行处罚的方法(静态工厂模式)。

代码如下:

package com.test.punish;

public interface IPunish {
void exePunish();
}

定义一个处罚的接口

package com.test.punish;
import org.springframework.beans.factory.InitializingBean; public class LatePunish implements IPunish,InitializingBean{
public void exePunish() {
System.out.println("罚100");
} public void afterPropertiesSet(){
PunishFactory.registerPunish("late", this);
} }

迟到处罚类

package com.test.punish;
import org.springframework.beans.factory.InitializingBean; public class SleepPunish implements IPunish,InitializingBean{
public void exePunish() {
System.out.println("罚款1000");
}
public void afterPropertiesSet(){
PunishFactory.registerPunish("sleep", this);
}
}

睡觉处罚类

package com.test.punish;
import org.springframework.beans.factory.InitializingBean; public class EarlyPunish implements IPunish,InitializingBean{
public void exePunish() {
System.out.println("警告");
} public void afterPropertiesSet(){
PunishFactory.registerPunish("early", this);
} }

早退处罚类

剩下的处罚类就不贴出来了。

package com.test.punish;
import java.util.HashMap;
import java.util.Map; public class PunishFactory { private static Map<String,IPunish> punishMap = new HashMap<String,IPunish>(); private PunishFactory() {} private static final IPunish EMPTY = new EmptyPunish(); //获取
public static IPunish getPunish(String state) {
IPunish result = punishMap.get(state);
return result == null ? EMPTY : result;
} //将处罚对象注册到这里
public static void registerPunish(String state,IPunish o){
punishMap.put(state, o);
} private static class EmptyPunish implements IPunish {
public void exePunish() {
// Empty class
}
}
}

生产具体处罚对象的静态工厂

重构后,处罚逻辑就可以这么写了,两行代码搞定

public class WorkPunish {
public static void main(String[] agrs){
String state ="late";
punish(state);
} //重构后的处罚逻辑
public static void punish(String state){
     //静态工厂类获取处罚对象
IPunish punish = PunishFactory.getPunish(state);
     //执行处罚逻辑
punish.exePunish();
}
}

重构后的处罚逻辑简单、清晰,后续新增一种情况,只需定义一个相应的类即可,根本不需要修改处罚逻辑,完全解耦合,这大大提高了代码的可读性和可维护性。

不过,运用静态工厂+策略模式,也存在弊端,那就是会增加很多类;但是,当每种情况的逻辑代码很多、很复杂的时候,那么这个弊端就可以忽略不计,其优势就完全展示出来了。

代码重构:用工厂+策略模式优化冗余的if else代码块的更多相关文章

  1. 代码重构:用工厂+策略模式优化过多的if else代码块

    最近在工作中优化了一段冗余的if else代码块,感觉对设计模式的理解和运用很有帮助,所以分享出来.鉴于原代码会涉及到公司的隐私,因此就不贴出来了.下面以更加通俗易懂的案例来解析. 假如写一个针对员工 ...

  2. 用工厂模式和策略模式优化过多的if-else

    多个if-else代码: @RunWith(SpringRunner.class) @SpringBootTest public class EducationalBackgroundTest { p ...

  3. Strategy 设计模式 策略模式 超靠谱原代码讲解

    先来假设一种情,我们需要向三种不同的客户做出不同的报价,一般来说要肿么设计呢,是不是马上会想到用IF,没有错,对于这种情况,策略模式是最好的选.大家可以这么理解,如果有情况需要用到大量的IF,那你用策 ...

  4. 利用策略模式优化过多 if else 代码

    前言 不出意外,这应该是年前最后一次分享,本次来一点实际开发中会用到的小技巧. 比如平时大家是否都会写类似这样的代码: if(a){ //dosomething }else if(b){ //dosh ...

  5. 策略模式优化过多的IF ELSE

    前言: 当if else的条件少的话,代码可阅读性及逻辑不影响阅读和扩展.一旦if else过多的话会导致逻辑比较混乱,不易扩展并且很容易出错. 实现方案: 1.定义一个@HandlerType注解, ...

  6. Java策略模式以及来自lambda的优化

    前言    设计模式是软件工程中一些问题的统一解决方案的模型,它的出现是为了解决一些普遍存在的,却不能被语言特性直接解决的问题,随着软件工程的发展,设计模式也会不断的进行更新,本文介绍的是经典设计模式 ...

  7. 商场促销-策略模式(和简单工厂模式很像的哇) C#

    还是那几句话: 学无止境,精益求精 十年河东,十年河西,莫欺少年穷 学历代表你的过去,能力代表你的现在,学习代表你的将来 废话不多说,直接进入正题: 首先按照大话设计模式的解释,在这里也总结下策略模式 ...

  8. CSS代码重构与优化之路(转)

    CSS代码重构与优化之路   阅读目录 CSS代码重构的目的 CSS代码重构的基本方法 CSS方法论 我自己总结的方法 写CSS的同学们往往会体会到,随着项目规模的增加,项目中的CSS代码也会越来越多 ...

  9. 新来的"大神"用策略模式把if else给"优化"了,技术总监说:能不能想好了再改?

    本文来自作者投稿,原作者:上帝爱吃苹果 目前在魔都,贝壳找房是我的雇主,平时关注一些 java 领域相关的技术,希望你们能在这篇文章中找到些有用的东西.个人水平有限,如果文章有错误还请指出,在留言区一 ...

随机推荐

  1. 自签名的https证书是不安全的

    一.项目内的需求 我们做的app都是企业级的应用,而企业级的应用的下载需要遵循itms协议,itms协议下需要https链接,这就需要你的服务器支持https的协议,该协议需要申请SSL证书,我们测试 ...

  2. Android 导入引用第三方项目

    环境:Android Studio 1.4 1 以源工程形式导入 第一步,导入项目 File--New--Import Module--->设置导入后的项目名称 第二部,在自己工程中添加Depe ...

  3. jQuery中下拉select、复选checkbox、单选radio的操作代码

    //select $("#Icon") //对象 $("#Icon").val() //取值 $("#Icon").val("fa ...

  4. bootstrap 轮播模板

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  5. [js高手之路]打造通用的匀速运动框架

    本文,是接着上文[js高手之路]匀速运动与实例实战(侧边栏,淡入淡出)继续的,在这篇文章的最后,我们做了2个小实例:侧边栏与改变透明度的淡入淡出效果,本文我们把上文的animate函数,继续改造,让变 ...

  6. Scala类型系统(sudden thought)

    http://docs.scala-lang.org/tour/lower-type-bounds.html中有一段代码 trait Node[+B] { def prepend(elem: B): ...

  7. 关闭eclipse自动弹出console的功能

    当启动项目后,console有值时就会弹出,挺烦人的,可以如下修改

  8. 【学习】苹果iPhone safari浏览器样式重置修复按钮圆角bug

    iPhone safari浏览器中,input按钮会按苹果的默认UI来渲染,例如,写的按钮明明是这个样的: 但是实际就会是这个样子: 怎么办呢? 为按钮添加:-webkit-appearance: n ...

  9. ZendStudio-12.5.0-win32.win32.x86_64.msi官方版本及破解工具

    网上的工具试了好多,最后下载的这个工具成功了,之前的N个工具都失败了 亲自试用,表示有效!!! ZendStudio-12.5.0-win32.win32.x86_64.msi官方版本下载地址:  百 ...

  10. laravel框架包资源分享

    最近发现laravel框架包很难下,楼楼之前下了两个版本,分享一下,希望对大家有所帮助.laravel-v5.2.15 链接: https://pan.baidu.com/s/1qYyhbFe 密码: ...