代码重构:用工厂+策略模式优化冗余的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 领域相关的技术,希望你们能在这篇文章中找到些有用的东西.个人水平有限,如果文章有错误还请指出,在留言区一 ...
随机推荐
- Spark版wordcount,并根据词频进行排序
import org.apache.spark.{SparkConf, SparkContext}/** * Created by loushsh on 2017/10/9. */object Wor ...
- MMORPG战斗系统随笔(四)、优化客户端游戏性能
转载请标明出处http://www.cnblogs.com/zblade/ 说到游戏性能,这是一个永恒的话题.在游戏开发的过程中,性能问题一直是我们研发需要关注的一个节点.当然,说句客观话,很多程序员 ...
- VTL(Velocity Templates Language,即Velocity模板语言)初识语法总结
1.velocity是一门基于Java语言的视图表现层模板引擎,它可以取代jsp,比jsp更高效. 2.velocity变量的定义与引用 (1).定义一个变量:#set ($a = "vel ...
- vue2购物车ch2-(商品列表显示)
1 index.html <!DOCTYPE html><html lang="en"><head> <meta charset=&quo ...
- 【转】NAS群晖DSM 5.0-4458安装教程
需要准备: 1.一个闲置的U盘,容量大于64M即可. 墙裂建议用如下U盘,可以隐藏成灰群晖,小巧方便. 闪迪(SanDisk)酷豆(CZ33)8GB U盘¥29.9京东商城 2.一台显示器,用于 ...
- HDU1212
大数MOD #include<cstdio> #include<cstdlib> #include<iostream> #include<algorithm& ...
- 用于Mysql操作的MySqlHelper类
using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Te ...
- win2003服务器定时自动重启命令
1. win2003可以这样自动重启: 新建一个命令行文件比如reboot.bat 内容如下:shutdown -r -t 30 在计划任务中新建一个任务,程序选择上面这个reboot.cmd文件,时 ...
- RobotFramework自动化测试框架-移动手机自动化测试Click Element At Coordinates关键字的使用
Click Element At Coordinates关键字通过一个具体的坐标点,来模拟点击一个Element,该关键字接收两个参数[ coordinate_X | coordinate_Y ]. ...
- Elasticsearch学习笔记 一
本文版权归博客园和作者吴双本人共同所有 转载和爬虫请注明原文地址 www.cnblogs.com/tdws. 本文参考和学习资料 <ES权威指南> 一.基本概念 存储数据到ES中的行为叫做 ...