重构-简化条件语句的使用

‘代码写了几年后,每每遇到看不下的代码,却又苦于找不到好的优化改善的办法,只能用读书少,读码少来挖苦自己了~’

当你在代码里看到一堆if-else,并且还嵌套的时候,第一反应一定是我去喝杯水吧,否则要吐了。今天先把Martin Fowler的原文搬上来,自己的例子后补

1. Decompose Condition(分解条件表达式)

从if,then,else三个段落中分别提炼出独立函数

if(date.before(SUMMER_START) && date.after(SUMMER_END)){
    charge = quantity*_winterRate+ _winterServiceCharge;
}
else{
    charge = quantity*_summerRate;
}

改造成

if(notSummer(date)){
    charge = winterChange(quantity);
}
else{
    charge = summerChange(quantity)
}

private boolean notSummer(Date date){
    return date.before(SUMMER_START) && date.after(SUMMER_END);
}

private double winterChange(int quantity){
    return quantity*_winterRate+ _winterServiceCharge;
}

private double summerChange(int quantity){
    return quantity*_summerRate;
}
2. 合并条件表达式

当有一系列的条件测试,都去执行相同的代码或者返回相同的结果时,把这些条件抽取到一个函数中,用逻辑运算联系起来

double disabilityAmount(){
    if(_seniority<2)return 0;
    if(_monthsDisabled > 12)return 0;
    if(_isPartTime) return 0;
}

改成

double double disabilityAmount(){
    if(isNotEligibleForDisability())return 0;
}

private boolean isNotEligibleForDisability(){
    return (_seniority<2)||(_monthsDisabled > 12)||(_isPartTime);
}
3. 合并重复的条件片段

如果在不同的分支里执行了相同的代码,则考虑将这样的代码放在条件之外执行

4. 移除控制标记

我们经常会写一些标记来传递结果或者用以记录判断何时停止的控制标示,将这种情况替换成break或者continue,或者return语句

void checkSecurity(String[] people){
    boolean found = false;
    if(int i=0;i<people.length;i++){
        if(!found){
            if(people[i].equals("Don")){
                sendAlert();
                found = true;
            }
            if(people[i].equals("John")){
                sendAlert();
                found = true;
            }
        }
    }
}

改成

void checkSecurity(String[] people){
    if(int i=0;i<people.length;i++){
        if(people[i].equals("Don")){
            sendAlert();
            break;
        }
        if(people[i].equals("John")){
            sendAlert();
            break;
        }
    }
}
5. Replace Nested Conditional with Guard Clauses

如果满足一个条件就能退出整个函数,则直接返回,不要在用else一层层去嵌套

double getPayAmount(){
    double result;
    if(_isDead){
        result = deadAmount();
    }else{
        if(_isSeparated){
            result = separatedAmount();
        }else{
            result = normalAmount();
        }
    }
}

改成

double getPayAmount(){
    double result;
    if(_isDead)return deadAmount();
    if(_isSeparated)return separatedAmount();
    return normalAmount();
}

Tips:有的时候可能你还得把条件做一次反转,如果它不能标示一个出口的时候,那它的反面也许是可以的。

6. 以多态取代条件表达式

如果根据不同的对象类型而选择不同的行为时,就可以把条件表达式的分支放进子类复写的函数中,然后将原始函数定义为抽象函数

7. 引入Null对象

之前傻乎乎的用了一个ListUtils#EMPTY_LIST。还想往里面put元素。今天看到这个,才知道NULL Object的设计模式。
学习下这个类就ok。
org.apache.commons.collections.ListUtils#EMPTY_LIST

空对象一定是个常量,它的任何成员都不会发生变化。

8. 引入断言

如果某段代码执行的条件一定要满足某个条件的话,那个该条件不被满足的时候就可以执行抛出异常。因此可以直接用断言语句进行判断,从而减少条件语句的使用。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值