重构手法:Replace Nested Conditional with Guard Clauses(以卫语句取代嵌套条件式)

本文讨论了条件表达式的两种形式及其用途,强调了卫语句在处理罕见情况时的重要性。卫语句通过提前检查并立即返回,提高了代码的可读性和效率。通过示例展示了如何将嵌套条件式替换为卫语句,以减少阅读理解的复杂性,并提倡在适当情况下打破「单一出口」规则,以追求更清晰的代码结构。
摘要由CSDN通过智能技术生成

条件表达式的形式

条件式通常有两种呈现形式。

第一种形式是:所有分支都属于正常行为。
第二种形式则是:条件式提供的答案中只有一种是正常行为,其他都是不常见的情况。

什么是卫语句

上面两类条件式有不同的用途,这一点应该通过代码表现出来。

如果两条分支都是正常行为,就应该使用形如「if…then…」的条件式;

如果某个条件极其罕见,就应该单独检查该条件,并在该条件为真时立刻从函数中返回。

这样的单独检查常常被称为「卫语句(guard clauses)」[Beck]。

Replace Nested Conditional with Guard Clauses

Replace Nested Conditional with Guard Clauses 的精髓就是:给某一条分支以特别的重视。如果使用if-then-else 结构,你对if 分支和else 分支的重视是同等的。 这样的代码结构传递给阅读者的消息就是:各个分支有同样的重要性。卫语句(guard clauses)就不同了,它告诉阅读者:『这种情况很罕见,如果它真的发生了,请做 一些必要的整理工作,然后退出。』

「每个函数只能有一个入口和一个出口」的观念,根深蒂固于某些程序员的脑海里。 我发现,当我处理他们编写的代码时,我经常需要使用Replace Nested Conditional with Guard Clauses。现今的编程语言都会强制保证每个函数只有一个入口, 至于「单一出口」规则,其实不是那么有用。在我看来,保持代码清晰才是最关键的:如果「单一出口」能使这个函数更清楚易读,那么就使用单一出口;否则就不必这么做。

范例

想像一个薪资系统,其中以特殊规则处理死亡员工、驻外员工、退休员工的薪资。这些情况不常有,但的确偶而会出现。
假设我在这个系统中看到下列伪代码:

 double getPayAmount() {
   double result;
   if (_isDead) result = deadAmount();
   else {
       if (_isSeparated) result = separatedAmount();
       else {
           if (_isRetired) result = retiredAmount();
           else result = normalPayAmount();
       };
   }
 return result;
 };

看到这里,如果你在读别人留下来的代码,是不是心里想着,如果。。。就。。。如果同时。。。就要。。。。一层一层读完你可能忘掉了前面的各种推演,这就是嵌套条件式恶心的地方。
现在我们改成卫语句的方式

double getPayAmount() {
   if (_isDead) return deadAmount();
   if (_isSeparated) return separatedAmount();
   if (_isRetired) return retiredAmount();
   return normalPayAmount();
 };

到这里,可读性大大提高,这时候读起来我会这么想:如果是XX员工,就发放XX员工的薪资。如果还体会不到卫语句的优势,除了上述三种员工外,剩下的都是正常员工,你还应该看到继续深层嵌套的正常员工的代码逻辑如下这样:

double normalPayAmount(){
    if (_level1) result = level1Amount();
    else {
        if (_level2) result = level2Amount();
        else result = level3Amount();
    };
}

这样的代码真的有必要读下去吗?如果我只是想知道退休薪资,这样的写法只会误导我把剩下的无用else语段看完,影响我的判断

另外一种情况也属于特殊不常见的情况比如上面的代码嵌套了好几层突然抛了异常或者return,你会不会想骂娘?这样的东西不应该属于提前检查的范畴吗?

再次强调:如果使用if-then-else 结构,你对if 分支和else 分支的重视是同等的。 这样的代码结构传递给阅读者的消息就是:各个分支有同样的重要性。卫语句(guard clauses)就不同了,它告诉阅读者:『这种情况很罕见,如果它真的发生了,请做 一些必要的整理工作,然后退出。』

此时将需要重视的语句直接提出来,抛出异常或者直接返回即可;

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值