代码重构:用工厂+策略模式优化过多的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 ...
- 利用策略模式优化过多 if else 代码
前言 不出意外,这应该是年前最后一次分享,本次来一点实际开发中会用到的小技巧. 比如平时大家是否都会写类似这样的代码: if(a){ //dosomething }else if(b){ //dosh ...
- 策略模式优化过多的IF ELSE
前言: 当if else的条件少的话,代码可阅读性及逻辑不影响阅读和扩展.一旦if else过多的话会导致逻辑比较混乱,不易扩展并且很容易出错. 实现方案: 1.定义一个@HandlerType注解, ...
- Strategy 设计模式 策略模式 超靠谱原代码讲解
先来假设一种情,我们需要向三种不同的客户做出不同的报价,一般来说要肿么设计呢,是不是马上会想到用IF,没有错,对于这种情况,策略模式是最好的选.大家可以这么理解,如果有情况需要用到大量的IF,那你用策 ...
- Java策略模式以及来自lambda的优化
前言 设计模式是软件工程中一些问题的统一解决方案的模型,它的出现是为了解决一些普遍存在的,却不能被语言特性直接解决的问题,随着软件工程的发展,设计模式也会不断的进行更新,本文介绍的是经典设计模式 ...
- Android 设计模式实战之关于封装计费代码库的策略模式详谈
写在之前 这周生活上出现了很多的不如意,从周一开始就觉得哪里出现了问题,然后就是各种烦躁的情绪,后来事情还真是如预感的那样发生了,很是心痛,但也无可奈何,希望大家都好好珍惜自己身边的人:友人,亲人,家 ...
- 商场促销-策略模式(和简单工厂模式很像的哇) C#
还是那几句话: 学无止境,精益求精 十年河东,十年河西,莫欺少年穷 学历代表你的过去,能力代表你的现在,学习代表你的将来 废话不多说,直接进入正题: 首先按照大话设计模式的解释,在这里也总结下策略模式 ...
- 新来的"大神"用策略模式把if else给"优化"了,技术总监说:能不能想好了再改?
本文来自作者投稿,原作者:上帝爱吃苹果 目前在魔都,贝壳找房是我的雇主,平时关注一些 java 领域相关的技术,希望你们能在这篇文章中找到些有用的东西.个人水平有限,如果文章有错误还请指出,在留言区一 ...
随机推荐
- hadoop框架结构介绍
近年,随着互联网的发展特别是移动互联网的发展,数据的增长呈现出一种爆炸式的成长势头.单是谷歌的爬虫程序每天下载的网页超过1亿个(2000年数据,)数据的爆炸式增长直接推动了海量数据处理技术的发展.谷歌 ...
- box-shadow 边框样式
如下 box-shadow: 0 1px 3px 0 rgba(0,0,0,.2), 0 1px 1px 0 rgba(0,0,0,.14), 0 2px 1px -1px rgba(0,0,0,.1 ...
- Bluez相关的各种tools的使用
7.1 Bccmd Bccmd是用来和CSR的芯片进行BCCMD(Bluecore command protocol)通讯的一个工具.BCCMD并非蓝牙协议栈的标准,而是CSR芯片的专属 ...
- 【Hibernate学习笔记-5.2】使用@Temporal修饰日期类型的属性
作者:ssslinppp 1. 摘要 关于日期类型,Java和数据库表示的方法不同: Java:只有java.util.Date和java.util.Calender两种: 数据库:dat ...
- ubuntu中为Pycharm添加快捷启动方式
1. sudo gedit /usr/share/applications/Pycharm.desktop 2.在文件中添加: [Desktop Entry] Type=Application Nam ...
- 小峰servlet/jsp(3)登陆功能实现
一.User模型: User.java: package com.java1234.model; public class User { private int id; private String ...
- [转]MSSQL 判断临时表是否存在
原文来自:http://www.cnblogs.com/szfhquan/p/4229150.html 方法一: 1 if exists (select * from tempdb.dbo.sysob ...
- MySQL 误删用户
误删除root用户&误删除所有用户 #----------------------------------------------------------------------------- ...
- Python 天气预报+微信
""" Description: 需要提供以下三个信息,在申请到的微信企业号当中可以找到 agentid corpid corpsecret Author:Nod Dat ...
- Leetcode 之Simplify Path @ python
Given an absolute path for a file (Unix-style), simplify it. For example,path = "/home/", ...