`
rainworlder
  • 浏览: 30283 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

过多if-else分支的优化

 
阅读更多

我想谈一谈这个话题是因为我的上一篇博客在ITEye上有一些朋友回复,说if-else过多的分支可以使用switch或者责任链模式等等方式来优化。确实,这是一个小问题,不过我们还是可以整理一下这个小问题的重构方式。

为什么要优化?

你没有看错。这是要放在第一条谈论的。

有许多人会说,叠起来一堆if-else分支,代码就不优雅了。可是,怎样去定义“优雅”的概念呢?再退一步说,即便不“优雅”,又有什么问题?

对于这样一段再普通不过的代码:

1
2
3
4
5
6
7
8
int code;
if("Name".equals(str))
    code = 0;
else if("Age".equals(str))
    code = 1;
else if("Address".equals(str))
    code = 2;
...

可以有好多种重构方式,但是使用这样的代码,虽然简陋,但在大多数情况下,并不会影响什么,比如,对可维护性没有影响。当然,如果你发现其中确有不好的一面,那就要考虑重构它。换言之,通常你首先要说出某段代码的问题(比如,你觉得这段代码不符合开闭原则,因为你希望保持这段代码闭合稳定),那么才去存在重构的必要,而不要总是使用“优雅”和“简洁”搪塞疑问。几乎所有的书上都说要写出优雅的、简洁的代码,这本身无可厚非,但是事物需要使用自己的判断,可不要被习惯性地洗了脑。

在我前一家公司,是典型的通讯和传统软件的公司,代码质量普遍不错,但是很多时候,会看到许许多多不够优雅的代码——也许你觉得不够简洁、美观,但是下代码严谨、清晰,我觉得这就很好。反之,某一些精巧的设计,可能会带来可阅读性和可理解性下降的问题。

寻找代替分支判断的方式

接下去我们再来考虑怎么样去重构优化过多的if-else分支。

程序逻辑最基本的组成就是分支、判断和循环。而过多if-else正是由于在某一个变化的点上,有许多判断条件和结果分支造成的。所以最基本的解决办法就是把多个判断条件合成一个,也就是把若干个分支合成一个。

但是在大多数情况下,条件判断的分支都是无法合并的。所以,我们需要把这个变化点通过别的途径封装起来,而不是采用if-else。

1. 用一个Map可以做到,if-else的变化点使用Map的get方法来代替:

1
2
3
4
5
6
Map typeCodeMap = new HashMap();
typeCodeMap.put("Name", 0);
typeCodeMap.put("Age", 1);
typeCodeMap.put("Address", 2);
...
int code = typeCode.get(type);

2. 枚举:

1
2
3
4
5
6
7
8
9
10
11
public enum Codes {
    Name(0), Age(1), Address(2);
     
    public int code;
    Codes(int code){
        this.code = code;
    }
}
 
//使用:
int code = Codes.valueOf(str).code;

3. 多态:

1
2
ICode iCode = (ICode)Class.forName("com.xxx." + str).newInstance();
int code = iCode.getCode();

当然,如果仅考虑从String转向int这样的转换,用这样的方式来简化分支判断逻辑,这个方式、这个例子不是很恰当。当然,这样的方式经常被用来做从字符串到具体对象的转换。

还有一些朋友说的这个模式那个模式来解决多if-else的问题,这些都是正确的,当然本质上也无一例外基于多态来实现的,所以我就不提及了。这些都不错,至少比那些老说用switch来代替if-else的有价值多了 :)

最后,对于如此小的一个问题,我要补充说明的一点是,看不得大片if-else和看不得大片new关键字一样,我觉得这是许多Java程序员的既有观念或者说习惯,甚至通病——这并不好。Java最有价值的地方不是它的语义语法也不是它的虚拟机跨平台和有多高性能,而在于它的社区它的无比丰富的类库,在于使用它的人可以从设计上和宏观上去思考问题。但是Java程序员,也包括我在内,很容易把这条路走得过于极端,比如遍地的Factory,比如漫山遍野的配置,比如永远也不会被复用的可复用代码,比如永远也不会被扩展的可扩展代码,还比如从前到后由内到外的分层,一层又一层。相对于这些方面无止境的追求,我们还是专注于要解决的问题,多写一些清晰可用的代码吧。

分享到:
评论

相关推荐

    verilog中多个else_if级联造成的综合电路的低效率及解决办法

    ### Verilog中多个else_if...通过使用多个`if_else`或`case`语句等方法替代`else_if`级联,可以在很大程度上优化这些问题,从而得到更加高效的硬件设计。对于工程师来说,理解这些细节并在实践中灵活运用是非常重要的。

    if_else&case;语句分析.pdf

    case语句通常用于替代多个if-else if条件分支,特别是在没有逻辑优先级需求的情况下。它是一种并行结构,所有的条件分支都是同时被检查的。这样可以避免逻辑级数过深导致的性能问题。文档中提到,尽管在RTL...

    使用策略模式改造if分支过多的方法

    在软件设计中,面对复杂的业务逻辑,特别是涉及多种条件判断的情况,传统的做法是使用if-else语句或者switch语句来实现。然而,随着需求的不断变化,这种做法可能导致代码结构变得臃肿且难以维护。在这种场景下,...

    如何优雅的替换掉代码中的ifelse

    然而,当条件分支过多时,`if-else`结构会导致代码变得冗长且难以维护,尤其是在大型项目中,这样的代码往往被称为“烂代码”。解决这个问题的一种优雅方式是采用策略模式、工厂模式或映射表等设计模式和技术手段。 ...

    if.rar_If..._跳转

    - **扩展形式**:`if...else` 和 `if...else if...else` 结构,用于处理多个条件分支。 - **嵌套使用**:`if` 语句可以嵌套在其他 `if` 语句中,形成多层条件判断,以实现更复杂的逻辑。 2. **跳转语句** - **...

    2 状态模式-MOOC课程内容.pdf

    当对象方法中存在大量依赖于对象状态的条件判断语句,如if-else或switch-case时,状态模式能将每个条件分支放入独立的类中,从而优化代码结构,提高可维护性和扩展性。 状态模式的主要参与者包括以下几个部分: 1....

    Python 语言程序设计3.docx

    - `if-elif-else` 结构允许实现多分支决策,可以处理更复杂的逻辑,避免过多嵌套,提高代码可读性。 4. **循环结构**: - `for` 循环常用于遍历序列(列表、元组、字符串等),例如计算平均数。循环变量会依次取...

    PIcC.rar_If..._PIC_picc _picc pdf

    描述中提到的“PIC C中高效率的循环if eles 语句.pdf”进一步细化了主题,它聚焦于在PIC C编程中如何通过优化`if...else`语句来提升循环的执行效率。在嵌入式系统中,尤其是资源有限的微控制器环境中,代码的效率至...

    JavaScript优化以及前段开发小技巧

    过多的if-else或switch语句会影响性能。惰性模式是一种解决方案,它延迟执行判断,直到实际需要时才进行。例如,当检测到第三方应用不支持localStorage时,可以使用惰性模式立即或首次使用时重定义获取和设置方法,...

    arm-instruction.zip_ARM instruction bne_BNE arm instruction

    BNE指令常用于循环、条件分支结构(如if-else)、错误处理和中断服务例程中。例如,在一个简单的for循环中,可以使用BNE指令在迭代条件不满足时跳出循环。 **优化技巧:** 1. **减少分支预测错误:** 由于现代...

    php 代码优化指南,给你的php加速

    减少代码中的条件分支(如if语句)数量可以提高代码执行速度。在可能的情况下合并条件分支。 #### 26. 优化对象创建 频繁创建和销毁对象会增加垃圾回收的压力。尽量重用对象或使用对象池技术来管理对象生命周期。 ...

    C语言程序优化.pdf

    文档提到了几种循环结构:`while()`, `if...else`, `do...while` 和 `for`。循环是编程中常用的结构,但是它们也会占用较多的CPU周期。循环优化主要包括减少循环次数、消除不必要的循环、循环展开等。例如,使用`do....

    PMD错误翻译整理

    2. 简化布尔返回值(SimplifyBooleanReturns):应当避免不必要的if-else语句结构,当返回布尔值时,如果逻辑判断简单直接,则可以省略复杂的if-else结构,直接返回判断结果。 3. 简化布尔表达式...

    程序设计基础样本.doc

    4. **限制使用 goto 语句**:过多的 goto 语句可能导致代码难以理解和调试,提倡使用结构化的控制流程(如 if-else,switch,for,while等)。 **构造化程序的基本构造**包括: - **顺序构造**:语句按照出现的顺序...

    Matlab中的goto函数

    3. **复杂条件分支**:当需要根据多个条件执行不同分支时,`goto`可以避免嵌套过多的`if-else`结构,使代码更简洁。 ```matlab check_conditions: if condition1 % 执行相应操作 elseif condition2 % 执行相应操作...

    Vue02.pdf

    - `v-else`和`v-else-if`:配合`v-if`进行条件分支。 - `v-for`:用于遍历数据并渲染列表。 - `v-on`(或简写`@`):事件监听器。 - `v-bind`(或简写`: `):属性绑定。 - `v-pre`:跳过该元素及其子元素的编译。 -...

    C语言程序编写规范,简化版

    - 尽可能避免复杂的if-else分支结构。 **3.2 避免使用GOTO:** - 不推荐使用GOTO语句,因为它可能导致程序流程混乱。 **3.3 IF语句只执行单一操作:** - IF语句内部只执行单一操作,避免IF内部包含多个语句。 *...

    阿里巴巴Java编程规范.pdf

    2. **switch-case语句**:避免过多的case分支,考虑使用if-else或策略模式替代。 3. **循环语句**:循环体内的逻辑应尽量简洁,避免复杂的嵌套循环。 ##### (八)注释规约 注释规约旨在提高代码的可读性和可维护...

    用C语言编写高效的ARM程序

    循环是程序中常见的结构,但在ARM架构下,过多的循环控制语句会导致性能下降。通过循环展开技术,可以减少每次循环的迭代次数,从而降低循环控制的开销。 #### 3.3 优化数据类型和存储访问 在ARM上,访问不同类型...

Global site tag (gtag.js) - Google Analytics