http://bj007.blog.51cto.com/1701577/345100/

switch语句是我们日常工作中最常见也是争论最多的(goto被忽视的前提下)。在重构中也把switch语句看成是一种代码的坏味道。但如何改造现有的switch代码并在今后去避免呢?本文从两方面进行探讨。
1 类型转化 
    在不同的抽象层次上对于同一个对象可能会用不同的定义。举个简单的例子,在计算器中,用户输入的操作符号可能是字符型的,而程序内部实现的时候需要用枚举型。因此可能就会有这样的函数。

        public class Calculator 
        { 
                public enum OPERATOR {Add, Minus, Multiply, Divide, Unknown};
                public static OPERATOR GetOperator(char ch) 
                { 
                        OPERATOR op = OPERATOR.Unknown;
                        switch (ch) 
                        { 
                                case '+': 
                                        op = OPERATOR.Add; 
                                        break; 
                                case '-': 
                                        op = OPERATOR.Minus; 
                                        break; 
                                case '*': 
                                        op = OPERATOR.Multiply; 
                                        break; 
                                case '/': 
                                        op = OPERATOR.Divide; 
                                        break; 
                                default: 
                                        break; 
                        } 
                        return op; 
                } 
        }

代码不长,不过写的过程中我却拷贝几次(case部分的代码)。原因就是代码的结构性重复还是比较严重的,而且如果以后支持其他新的操作时候,这代码不仅要改变,而且还会不断变冗长。认真想想,避免的办法还是有的,用Dictionary做一个映射表就可以实现。

     public class Calculator 
        { 
                public enum OPERATOR { Add, Minus, Multiply, Divide, Unknown};
                static private var OperatorMap = new Dictionary<char, OPERATOR> { 
                        { '+', OPERATOR.Add }, 
                        { '-', OPERATOR.Minus }, 
                        { '*', OPERATOR.Divide }, 
                        { '/', OPERATOR.Multiply }, 
                };
                public static OPERATOR GetOperator2(char ch) 
                { 
                        if (OperatorMap.ContainsKey(ch)) 
                                return OperatorMap[ch]; 
                        else 
                                return OPERATOR.Unknown; 
                } 
        }

这样,不仅代码简洁了很多,而且从本质上已经从逻辑代码维护变成了映射表的维护。
2 动作调用 
接续刚才的例子,这次不仅要实现操作符转化,而且要实现真正的运算。第一个反应又是想到了switch。实现如下:

     public class Calculator 
        { 
                static public int Calculate(char op, int number1, int number2) 
                { 
                        int result = 0;
                        switch (GetOperator(op)) 
                        { 
                                case OPERATOR.Add: 
                                        result = number1 + number2; 
                                        break; 
                                case OPERATOR.Minus: 
                                        result = number1 - number2; 
                                        break; 
                                case OPERATOR.Multiply: 
                                        result = number1 * number2; 
                                        break; 
                                case OPERATOR.Divide: 
                                        result = number1 / number2; 
                                        break; 
                                default: 
                                        throw new Exception("Unsupported Operation!"); 
                        } 
                        return result; 
                } 
        }

跟之前遇到的问题有些类似,不过这回需要调用函数。通过.Net环境提供的Dictionary以及Func Delegate的解决如下:

        public class Calculator 
        { 
                static private Dictionary<OPERATOR, Func<int, int, int>> calculationAction = new Dictionary<OPERATOR, Func<int, int, int>> { 
                        { OPERATOR.Add, Add }, 
                        { OPERATOR.Minus, Minus }, 
                        { OPERATOR.Multiply, Multiply }, 
                        { OPERATOR.Divide, Divide }            
                };
                public static OPERATOR GetOperator2(char ch) 
                { 
                        if (OperatorMap.ContainsKey(ch)) 
                                return OperatorMap[ch]; 
                        else 
                                return OPERATOR.Unknown; 
                }
                static int Add(int number1, int number2) 
                { 
                        return number1 + number2; 
                }
                // Others are omitted here for brevity 
        }

通过这个简单的例子,我们可以看出Switch通常会带来一些结构性的重复,通过利用Dictionary等二维表结构,我们可以尽量去避免switch语句,从而实现更好的灵活性和可维护性。最后需要支持的是,在Switch语句的重构过程中需要注意几点:
* 共通化以使得各个case中调用函数的签名一致 
* if...else if...else结构同switch在某些情况下具有互换性,也可以考虑这种方法 
* switch语句的重构是也可以考虑State Pattern以及Strategy Pattern等设计模式。选择的时候可以考虑视具体情况而定。

本文出自 “林家男孩” 博客,请务必保留此出处http://bj007.blog.51cto.com/1701577/345100

转载于:https://www.cnblogs.com/tylertang/p/6588757.html

C#: switch语句的重构『网摘』相关推荐

  1. C#: switch语句的重构

    switch语句是我们日常工作中最常见也是争论最多的(goto被忽视的前提下).在重构中也把switch语句看成是一种代码的坏味道.但如何改造现有的switch代码并在今后去避免呢?本文从两方面进行探 ...

  2. 用重构指导Clean Code(二):依恋情结和switch语句

    书接上回,我们继续聊如何用重构指导Clean Code. 在Clean Code的3.4节中有这样一段代码(代码清单3-4).(第3章主要讲的是函数,而3.4节讨论的是switch语句.) publi ...

  3. java 圈复杂度_关于Java:降低Switch语句的循环复杂度-Sonar

    我想减少开关盒的圈复杂度 我的代码是: public String getCalenderName() { switch (type) { case COUNTRY: return country = ...

  4. 精品网摘:大内核锁将何去何从

    精品网摘:大内核锁将何去何从 注:本文转载自CSDN博客universus的专栏:http://blog.csdn.net/universus/article/details/5623971 大内核锁 ...

  5. c语言switch scanf语句,c语言switch语句 谢谢·!~!~

    c语言switch语句 谢谢·!~!~以下文字资料是由(历史新知网www.lishixinzhi.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧! c语言switch语句 谢谢·!~ ...

  6. c语言case标号是连续的吗,在switch语句中,case后的标号只能是什么?_后端开发...

    在switch语句中,case后的标号只能是常量表达式.在一个特定的switch语句中,每一个case常量都必须具有举世无双的值,不能够反复.然则switch语句能够包括多个case标签. switc ...

  7. 为什么不能在字符串上使用switch语句?

    此功能是否将在以后的Java版本中使用? 有人可以解释为什么我不能这样做吗,例如Java的switch语句的技术方式? #1楼 Groovy轻而易举: 我嵌入了groovy jar并创建了一个groo ...

  8. c语言商场收款程序,c语言 如何用switch语句编写一个有关商场购物金额优惠的选择程式...

    c语言 如何用switch语句编写一个有关商场购物金额优惠的选择程式以下文字资料是由(历史新知网www.lishixinzhi.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧! c语 ...

  9. 【自学Java】Java switch语句

    Java switch语句 Java switch语句教程 在 Java 语言 中如果遇到多选一的场景,可以使用 switch 将其简化,让程序更加简洁易懂.switch 语句可以被 if-else ...

  10. break在java语言中什么意思_在Java语言的控制结构中,break语句是经常用到的语句。在switch语句中break语句的作用是( )_学小易找答案...

    [单选题]( )是一个综合性的网络营销工具,在所有的网络营销工具中也是最基本.最重要的一个. [单选题]给出下列的代码,哪行在编译时可能会有错误( ) 1 public static void mai ...

最新文章

  1. 你需要了解的load和initialize
  2. 实验LVS+keepalived
  3. ubuntu16.04 安装微信和qq
  4. opencv图像操作:读取,裁剪,保存,缩放,遍历和读取文件夹图片
  5. user agent stylesheet对格式的影响
  6. GitHub多人协作简明教程
  7. mybatis float 小数0 不显示_卧槽!用 float 存储金额,老板说损失从工资里扣!
  8. 记一次为公司搭建maven私服的过程
  9. 服务器托管用户支招选择IDC经验
  10. ubuntu搜狗输入法下载
  11. 【2022第十届‘泰迪杯’挑战赛】A题:害虫识别完整版(大致思路。详细过程和代码以及结果csv在压缩包中)
  12. ubuntu快捷键及Linux下一些主要目录
  13. CString 使用详解
  14. virtual Box与Vagrant的安装与踩坑
  15. Nginx 反向代理,提供 http 访问,代理 https 外站内容
  16. 计算机/微机组成及相关概念
  17. Zabbix unreachable poller processes more than 75% busy
  18. 首届全国智能制造(中国制造2025)创新创业大赛
  19. python爬虫——爬取淘票票正在热映电影
  20. Vue天地图之图层类型切换

热门文章

  1. 2013北理机试题——中缀算术表达式对应二叉树的先序遍历
  2. 【大规模深度强化学习(一) 】深度强化学习中的异步方法(A3C)
  3. Texar安装、Textgenrnn安装
  4. MLP多层感知机原理简介+代码详解
  5. 控制台——EventLog实现事件日志操作
  6. unity 动画 音频播放
  7. Linux笔记(五) - 用户管理命令
  8. JavaScript Date时间对象
  9. set.seed(7)什么意思
  10. JS讲解跟遇到的问题