代码重构:用工厂+策略模式优化冗余的if else代码块
最近在工作中优化了一段冗余的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代码块的更多相关文章
- 代码重构:用工厂+策略模式优化过多的if else代码块
最近在工作中优化了一段冗余的if else代码块,感觉对设计模式的理解和运用很有帮助,所以分享出来.鉴于原代码会涉及到公司的隐私,因此就不贴出来了.下面以更加通俗易懂的案例来解析. 假如写一个针对员工 ...
- 用工厂模式和策略模式优化过多的if-else
多个if-else代码: @RunWith(SpringRunner.class) @SpringBootTest public class EducationalBackgroundTest { p ...
- Strategy 设计模式 策略模式 超靠谱原代码讲解
先来假设一种情,我们需要向三种不同的客户做出不同的报价,一般来说要肿么设计呢,是不是马上会想到用IF,没有错,对于这种情况,策略模式是最好的选.大家可以这么理解,如果有情况需要用到大量的IF,那你用策 ...
- 利用策略模式优化过多 if else 代码
前言 不出意外,这应该是年前最后一次分享,本次来一点实际开发中会用到的小技巧. 比如平时大家是否都会写类似这样的代码: if(a){ //dosomething }else if(b){ //dosh ...
- 策略模式优化过多的IF ELSE
前言: 当if else的条件少的话,代码可阅读性及逻辑不影响阅读和扩展.一旦if else过多的话会导致逻辑比较混乱,不易扩展并且很容易出错. 实现方案: 1.定义一个@HandlerType注解, ...
- Java策略模式以及来自lambda的优化
前言 设计模式是软件工程中一些问题的统一解决方案的模型,它的出现是为了解决一些普遍存在的,却不能被语言特性直接解决的问题,随着软件工程的发展,设计模式也会不断的进行更新,本文介绍的是经典设计模式 ...
- 商场促销-策略模式(和简单工厂模式很像的哇) C#
还是那几句话: 学无止境,精益求精 十年河东,十年河西,莫欺少年穷 学历代表你的过去,能力代表你的现在,学习代表你的将来 废话不多说,直接进入正题: 首先按照大话设计模式的解释,在这里也总结下策略模式 ...
- CSS代码重构与优化之路(转)
CSS代码重构与优化之路 阅读目录 CSS代码重构的目的 CSS代码重构的基本方法 CSS方法论 我自己总结的方法 写CSS的同学们往往会体会到,随着项目规模的增加,项目中的CSS代码也会越来越多 ...
- 新来的"大神"用策略模式把if else给"优化"了,技术总监说:能不能想好了再改?
本文来自作者投稿,原作者:上帝爱吃苹果 目前在魔都,贝壳找房是我的雇主,平时关注一些 java 领域相关的技术,希望你们能在这篇文章中找到些有用的东西.个人水平有限,如果文章有错误还请指出,在留言区一 ...
随机推荐
- Java历程-初学篇 Day04选择结构(1)
一,if 1,单分支 if(条件){ } 示例: 2,双分支 if(条件){ }else{ } 示例: 3,多重if if(条件){ }else if(条件){ }else{ } 示例: 4,嵌套if ...
- HDU3605 Escape
思想:缩点+sap Max,t还可以缩小,优化,高数课写的,有点丑,暂时懒得改. #include<cstdio> #include<cstdlib> #include< ...
- ListBox数据绑定无效
public class DataList { public List<string> listSource; private DataTable table; public DataLi ...
- uvalive 2965 Jurassic Remains
https://vjudge.net/problem/UVALive-2965 题意: 给出若干个由大写字母组成的字符串,要求选出尽量多的字符串,使得每个大写字母出现的次数是偶数. 思路: 如果说我们 ...
- (@WhiteTaken)设计模式学习——观察者模式
忙里抽闲,继续学习设计模式,作为自己的读书笔记,这次介绍Java下实现的观察者模式. 观察模式需要了解的三个概念: 被观察者:被观察的对象,发生变化会通知观察者集合(存放观察者的容器) 观察者:有up ...
- XtraReports 入门教程
一个链接:http://www.cnblogs.com/springSky/tag/XtraReports%20%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B/ 与之相同功能 ...
- uva 10118,记忆化搜索
这个题debug了长达3个小时,acm我不能放弃,我又回来了的第一题! 一开始思路正确,写法不行,结果越改越乱 看了网上某神的代码,学习了一下 coding+debug:4小时左右,记忆化搜索+dp类 ...
- 在HTM中显示播放视频
注意:video中source 源文件地址src替换成你的video路径<html> <button onclick="playPause();">播 ...
- ASP.NET Core 2.0 in Docker on Windows Container
安装Docker for Windows https://store.docker.com/editions/community/docker-ce-desktop-windows 要想将一个ASP. ...
- 队列(存储结构数组)--Java实现
/*队列:其实也是一种操作受限的线性表 *特点:先进先出 *队尾指针:负责元素的进队 *队头指针:负责元素的出队 *注意:普通队--容易浪费空间,一般队列使用最多的就是循环队列--指针环绕 *队列的实 ...