switch方法重构案例

AI权益加码!Claude Code、Cursor等20+工具免费用! 购周边限时加赠Coding Plan Lite,畅享主流AI工具!学习进阶更高效! 阅读详情

面向对象语言开发过程中对于switch语句是很敏感的,大多数switch基本都可以通过多态方式进行重构,从而使程序获得较好的拓展能力,最近项目开发中遇到这样一个案例,在此分享一下。

重构前程序

Java代码 复制代码 收藏代码
  1. public void update(Request newReq){
  2. Request existReq=dao.getExist();
  3. Type _type=newReq.getMsgType();//Type为枚举类型
  4. ...
  5. switch (_type) {
  6. case A_MSG:
  7. existMsg = methodA(existReq);
  8. case B_MSG:
  9. existMsg = methodB(existReq, newReq);
  10. case C_MSG:
  11. if(...) {existReq = methodA(existReq);}
  12. else { existReq=methodB(existReq, newReq);}
  13. }
public void update(Request newReq){
        
               Request existReq=dao.getExist();
               Type _type=newReq.getMsgType();//Type为枚举类型
               ...
                switch (_type) {
                    case A_MSG:
                        existMsg = methodA(existReq);
                    case B_MSG:
                        existMsg = methodB(existReq, newReq);
                    case C_MSG:
                        if(...) {existReq = methodA(existReq);}
                        else { existReq=methodB(existReq, newReq);}
                }
Java代码 复制代码 收藏代码
  1. dao.update(existReq);
                dao.update(existReq);
}
Java代码 复制代码 收藏代码

根据重构一般原则需要对_type进行抽象并建立继承关系,这里命名基类为MsgType

Java代码 复制代码 收藏代码
  1. public abstract MsgType{
  2. protected Request methodA(Request existReq,
  3. Request newReq) {
  4. ...
  5. }
  6. protected Request methodB(Request existReq) {
  7. ...
  8. }
  9. public abstract Request changeRequest(Request existReq, Request newReq);
  10. }
public abstract MsgType{
	protected Request methodA(Request existReq,
			Request newReq) {
		...
	}

	
	protected Request methodB(Request existReq) {
		...
	}

	public abstract Request changeRequest(Request existReq, Request newReq); 
}
Java代码 复制代码 收藏代码
  1. 然后针对各Msg类型建立相应子类,并实现changeRequest方法
然后针对各Msg类型建立相应子类,并实现changeRequest方法

Java代码 复制代码 收藏代码
  1. public AMsgType extends MsgType{
  2. public Request changeRequest(Request existReq, Request newReq){
  3. return super.methodA();
  4. }
  5. }
public AMsgType extends MsgType{
	
	public  Request changeRequest(Request existReq, Request newReq){
              return super.methodA(); 
  }
}
Java代码 复制代码 收藏代码
  1. public BMsgType extends MsgType{
  2. public Request changeRequest(Request existReq, Request newReq){
  3. return super.methodB();
  4. }
  5. }
public BMsgType extends MsgType{
	
	public  Request changeRequest(Request existReq, Request newReq){
              return super.methodB(); 
  }
}
Java代码 复制代码 收藏代码

之后创立一个工厂方法,注意,这里仍然有一个switch,因为我们需要根据msgType来创建相应的type类。

Java代码 复制代码 收藏代码
  1. public class MsgTypeFactory {
  2. public static MsgType createMsgType(Request newReq) {
  3. switch (newReq.getMsgType()) {
  4. case A_MSG:
  5. return new AMsgType();
  6. case B_MSG:
  7. return new BMsgType();
  8. case C_MSG:
  9. return new CMsgType();
  10. default:
  11. throw new RuntimeException("不兼容消息类型:"+newReq.getMsgType());
  12. }
  13. }
  14. }
public class MsgTypeFactory {

	public static MsgType createMsgType(Request newReq) {
		switch (newReq.getMsgType()) {
		case A_MSG:
			return new AMsgType();
		case B_MSG:
			return new BMsgType();
		case C_MSG:
			return new CMsgType();
		default:
			throw new RuntimeException("不兼容消息类型:"+newReq.getMsgType());
		}
	}
}

工具已经齐备,可以向原程序开炮了,重构后程序如下:

Java代码 复制代码 收藏代码
  1. public void update(Request newReq){
  2. Request existReq=dao.getExist();
  3. MsgType msgType=MsgTypeFactory.createMsgType(newReq);
  4. //根据不同消息类型做不同作更新操作
  5. existReq=msgType.changeRequest(existReq, newReq);
  6. dao.update(existReq);
  7. }
 public void update(Request newReq){
        
               Request existReq=dao.getExist();
               MsgType msgType=MsgTypeFactory.createMsgType(newReq);
    
    //根据不同消息类型做不同作更新操作
      existReq=msgType.changeRequest(existReq, newReq);

               dao.update(existReq);
}

之前还对factory里面的switch方法耿耿于怀,以为重构前功尽弃,但是仔细一想,其实现在的程序已经完成了service层的解耦,当有一个新Msg类型添加的时候只需要增加相应的子类,在工厂方法配制一下就可以了,同样当对某个msg变更处理策略时也可以控制在很小的修改范围。

据此,我的结论是:重构过程不是一个教条的过程,或许最后还是没办法完全消灭switch,但是重构的目的达到了就已经算是成功。

【高质量代码系列2】switch 语句重构技巧总结 switch 语句在日常开发中,常常用来根据不同的类型,执行不同的操作。如果类型很多,整个swtich代码会变得很臃肿,代码可扩展性、可阅读性都很差。针对这个问题,我们可以考虑使用多态来解决,将每个类型的行为封装到一个子类中。下面以加减等计算类型的操作为例说明这个问题 1public enum CalculateType { 2 3 ADD("add","加法"),SUB("sub","... 阅读详情

相关推荐

重构-改善既有代码的设计--重构,第一个案例,java面试八股文汇总

这份清华大牛整理的进大厂必备的redis视频、面试题和技术文档祝大家早日进入大厂,拿到满意的薪资和职级~~~加油!!!帮助,可以添加下面V无偿领取!(备注Java)**[外链图片转存中…(img-Cz8ZVmxS-1711196361264)]这份清华大牛整理的进大厂必备的redis视频、面试题和技术文档祝大家早日进入大厂,拿到满意的薪资和职级~~~加油!!![外链图片转存中…(img-ouwuH5tt-1711196361265)]本文已被。

m0_60575487的博客 1085

switch进行拆分重构,降低复杂度,6种方式

如何对switch进行拆分重构 在我们编写代码的时候,常常遇到许多if-else或者switch的情况,这种情况下如果分支过多,会导致我们的最大复杂度过大,可能在公司编代码的时候通过不了检测,我们可以对这些分支提取成方法单独存在,也只是能降低平均圈复杂度,最大还是无济于事,所以这里我写了三种方式来降低复杂度: 1、利用多态,也就是方法重写 2、方法重写加反射 3、纯反射 如果谁有更好的方法,欢迎指正分享 先来看一下普通的switch语句: public class Test4 { public s

IT_CREATE的博客 9147

嵌入式开发实战:如何用QP框架重构你的状态机代码(附炸弹拆除案例

本文详细介绍了如何使用QP框架重构嵌入式系统中的状态机代码,解决传统switch-case实现的可维护性问题。通过炸弹拆除案例实战,展示QP框架在层次状态机设计、事件驱动架构和代码优化方面的优势,帮助开发者提升嵌入式系统的开发效率和可维护性。

weixin_27219587的博客 367

简单易懂读《重构》 - Switch Statement (switch语句过多)

少用switch语句,尽量用多态取代

Hermaeus Mora's Apocrypha 2368

c语言 switch case 太多优化/重构[二]

c语言 switch case 太多优化/重构[二]1. 背景 - 某该函数switch case 复杂度太高 ,函数太长 pclint不过2. 解决 - 建表,查表处理3. witch case 原理/代码优化 重构参考: 1. 背景 - 某该函数switch case 复杂度太高 ,函数太长 pclint不过 CHAR * AB_FUN_XXXX(IN ULONG ulResult) { UINT uiRcID; switch (ulResult) { case ERROR_SUCCESS:

哈尼的博客 6121

避免过多switch case分支语句,导致增加方法复杂度的措施

避免过多switch case分支语句,导致增加方法复杂度的措施

liubin5620的博客 1万+

c语言圈复杂度switch,C语言switch/case圈复杂度优化重构

软件重构是改善代码可读性、可扩展性、可维护性等目的的常见技术手段。圈复杂度作为一项软件质量度量指标,能从一定程度上反映这些内部质量需求(当然并不是全部),所以圈复杂度往往被很多项目采用作为软件质量的度量指标之一。C语言开发的项目中,switch/case代码块是一个很容易造成圈复杂度超标的语言特性,所以本文主要介绍下降低switch代码段的重构手段(如下图)。switch圈复杂度优化重构可分为两部...

weixin_32821913的博客 455

重构总结 - 第一个案例总结

本文通过一个影片出租店程序案例,详细展示了代码重构的过程。初始代码通过Customer、Movie和Rental三个类实现租赁计算功能,存在长方法、重复代码等问题。重构步骤包括:1)提取switch语句到独立函数;2)优化变量命名;3)将金额计算逻辑移至Rental类;4)提取常客积分计算逻辑;5)用查询替代临时变量;6)使用多态替代switch语句,创建Price抽象类及其子类。最终实现了更清晰、可维护的代码结构,通过继承体系处理不同影片类型的计费规则,体现了重构改善代码质量的价值。

小人物的草稿本 1426

c语言圈复杂度switch,干货|C语言switch\/case圈复杂度优化重构

点击上方“中兴开发者社区”,关注我们每天读一篇一线开发者原创好文 ▍作者简介作者陈彬是一名Linux驱动开发工程师,对Linux内核、软件设计和敏捷有较浓厚的兴趣和长期实践经验。自从项目建立起代码质量规范和监控工具后,如何重构高圈复杂度的代码,特别是switch/case的圈复杂度,是同事间比较普遍的一个问题,这正是写本篇文章的起因。希望这篇文章对大家能有所启发。C语言switch/case圈复杂...

weixin_42339991的博客 1160

csharp进阶练习题:重构出一个switch语句的解释【难度:2级】--景越C#经典编程题库,不同难度C#练习题,适合自学C#的新手进阶训练

csharp进阶练习题:重构出一个switch语句的解释【难度:2级】: 团 这个习题的目的是重构switch语句,并用字典"跳转表"代替 问题 尽管switch语句可以快速执行,是一个简单的结构,以掌握他们可以成为笨拙因为他们要增加维护的噩梦. 此外,他们不会轻易鼓励"打开关闭"的原则.考虑到这一点,我们会从代码中删除switch叙述,用它可以像一个"跳转表"中使用的辞典更换. 解决方案 您的...

景越c#经典编程题库(csharp programming training) 608

从各处收集的switch语句

1 重构之重复代码: 2 3 1.(重复代码是)语义一致的逻辑 4 反例:语义一致的逻辑产生了多个实体 5 缺点:如果你为语义一致的逻辑产生了多个实体,那么当需要修改这个逻辑时,你必须保证同时修改所有的实体,并确保它们是一致的。否则,程序就会产生bug。无疑,这么做会额外增加很多的不必要的工作量。 6 ...

diaopitian0181的博客 187

重构思维系列-如何写出好代码1

package service.alarmClock; import javax.sound.sampled.*; import java.io.File; import java.io.IOException; import java.text.SimpleDateFormat; import java.util.Calendar; public class AlarmClock { /** * 闹钟提醒-功能介绍: * 每当早上、中午、晚上时,分别有对应类型的播放音乐,.

初级程序猿一步步进阶高级的博客 428

Java多层嵌套if的优化_一个多层 if / else 嵌套的代码重构案例(JavaScript)

背景日常开发经常会遇到复杂的条件判断, 一般做法就是用if/else, 或者优雅一点用switch来实现多个条件的判断. 如果条件越来越多, 会导致代码越来越臃肿, 如何使用更优雅的方式来实现呢?案例先来看一段代码:const clickHandler = (status) => {if(status === 1) {sendLog('processing')jumpTo('IndexPag...

weixin_39628268的博客 2917

陈旧语法密度之二——switch case和if-else if-else的坏处

switch case和if – else if - else的坏处要想写出超长方法,就写一个switch-case,如果觉得不够长,就再写一个。本人亲自重构过的有记录的最长的一个方法包含502个switch-case,加上每个case中一行实际工作代码,外加一些函数声明等,最终高达1030行。值得提一下的是重构后这个方法只有1行实际工作代码。实际上整个2000多行的模块重构后一共也只有180行。...

陈勇的博客 - Scrum 敏捷开发培训咨询,绩效管理,团队管理,《火星人敏捷开发手册》 1959

软件重构的一点总结

昨天领导让我把之前做的软件及资料整理出来,供他人参照学习,我说好。等到我打开之前的代码的时候,加上最近学习设计模式的一些体会,发觉有点不堪入目。于是决定将代码重构一下,尽量比之前有所改进。 1、model类,左侧选定的树节点改变后的判断,由if 改为 switch case,看似好点了,可是里面一大坨类似的代码,于是写了一个

Peter-H 1083

重构(Martin Fowler)——简化条件表达式

条件逻辑有可能十分复杂,因此本章提供一些重构手法,专门用来简化它们。其中一项核心重构就是Decompose Conditional 将一个复杂的条件逻辑分成若干小块。 本章的其余重构手法可用以处理另一些重要问题: 如果你发现代码中的多处测试有相同的结果,应该实施Consolidate Conditional Expression 如果条件代码中有任何重复,可以运用Consolidate Duplicate Conditional Fragments 面对对象程序的条件表达式通常比较少,因为很多条件

qq_41605114的博客 717

重构if...else...或者switch程序块

我们在开发asp.net时,经常有使用if...else...或者是使用switch来进行多个条件判断。如下面这篇《用户控件(UserControl) 使用事件 Ver2》http://www.cnblogs.com/insus/archive/2011/11/18/2253605.html,就是一段代码: 其实按上面的写法一点问题都没有,但是我们在审检代码看到这段代码时似乎要花点时间阅读,用意...

weixin_30617561的博客 76

java第一章代码,java 代码复建-第一章(分解并重组statement())

java 代码重构-第一章(分解并重组statement())2.1 把switch代码在方法中抽出第一个明显引起我注意的就是长得离谱的statement() 。每当看到这样长长的函数,我就想把它大卸八块。要知道,代码区块愈小,代码的功能就愈容易管理,代码的处理和搬移也都愈轻松。重构过程的第一阶段中,我将说明如何把长长的函数切开,并把较小块的代码移至更合适的class 内。我希望降低代码重复量,从...

weixin_39706367的博客 201
上一篇: Decorator(装饰)模式
下一篇: 黑马程序员-String类
dahe5
博客等级 码龄14年 2粉丝 0原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值