zoukankan      html  css  js  c++  java
  • 重构之简化条件表达式

          条件逻辑有可能十分复杂,因此本章提供一些重构手法,专门用来简化它们。其中一项核心重构就是Decompose Conditional,可将一个复杂的条件逻辑分成若干小块。这项重构很重要,因为它使逻辑和操作细节的分离。

         本章的其余重构手法可用以处理另一些重要问题,如果你发现代码中的多处测试有相同的结构,应该实施Consolidate Conditional Expression,如果条件代码中有任何重复,可以运用Consolidate Duplicate Conditional Fragment 将重复成分去掉。

          较之于过程化程序而言,面向对象因为多态的机制可以简化条件行为的细节

    1. Replace Nested Condition with Guard Clauses(以卫语句

    取代嵌套条件表达式) 

            Clauses[klɔ:zis] :字句      Guard[ga:d]: 守卫、看守    Nesting: 嵌套

            范例:

                   想象一个薪酬系统,其中以特区规则处理死亡、驻外、退休员工的薪资,这些情况不常有,但偶然会出现

             常规编码:

       1:      private double getPlayAmount(){
       2:          double result;
       3:          if(_isDead){
       4:              result = deadAmount();
       5:          }else{
       6:              if(_isSeparated){
       7:                  result = separatedAmount();
       8:              }else {
       9:                  if(_isRetired){
      10:                      result = retiredAmount();
      11:                  }else {
      12:                      result = normalAmount();
      13:                  }
      14:              }
      15:          }
      16:          return result;
      17:      }
     
       分析: 条件表达式通常有两种表现形式。第一种:所有的分支都属于正常行为,应该用
                 if..else表达出来。第二种:条件表达式提供的答案中只有一种是正常行为,其
                 他都是不常见的行为。此时就要单独检查该条件,并在该条件为真时立刻从函数
                 中返回,这种单独检测常常为称为“卫语句”通过分析题意,我们知道该函数主
                 体是付普通情况的工资,而死亡、驻外、退休属于特区情况,因此我们把他们做
                 为卫语句处理,修改后为:
          
       1:      private double getPlayAmount(){
       2:          
       3:          if(_isDead){
       4:              return deadAmount();
       5:          }
       6:          
       7:          if(_isSeparated){
       8:              return separatedAmount();
       9:          }
      10:          
      11:          if(_isRetired){
      12:              return retiredAmount();
      13:          }
      14:   
      15:          return normalAmount();
      16:      }
     

         2. Decompose Conditional (分解条件表达式) 

            decompose [ˌdi:kəmˈpəuz] :分解、腐烂

             -----你有一个复杂的条件语句(if、then、else),从if ,then,else三个段落中分别提炼出独立函数

             假设我要计算购买某样商品的总价(总价=数量 * 单价),而这个商品在冬季和夏季的单价是不同的。

        if(data.before(SUMMER_START) || data.after(SUMMER_END)){
            charge = quantity * _winterRate ;
        }else{
            charge = quantity * _summerRate
        }

            分析:复杂的条件逻辑是最常导致复杂度上升的原因之一,常见的做法是1) 将if段提炼出来,构成一个独立的函数  2)将then和else段提炼出来构成一个独立的函数

            修改后的代码为:

        if(notSummer(data)){
            charge = winterCharge(quantity);
        }else{
            charge = summerCharge(quantity);
        }
        
        private boolean notSummer(Data data){
            return data.before(SUMMER_START) || data.after(SUMMER_END);
        }
        
        private double summerCharge(int quantity){
            return quantity * _summerRate;
        }
        
        private double winterCharge(int quantity){
            return quantity * _winterRate;
        }

         通过以上的简化,条件表达式逻辑块就像代码注释一样清晰、明了

    3. Consolidate Conditional Expression (合并条件表达式)       

           ----你有一系列的条件测试,都得到相同的结果,将这些测试合并为一个条件表达式,并将这个条件表达式提炼为一个独立的函数

           示例:

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

          分析:有时候你会发现一连串的检查条件,虽然条件各不相同,但是最终行为却一致,这种情况一般是用“逻辑与”或者“逻辑或”把他们合并为一个条件表达式,使代码更清楚。 合并后

        double disabilityAmount(){
            if(isNotAbility()){
                return 0
            }
        }
        
        boolean isNotAbility(){
            return ((_seniority < 2) || (_months > 12) || _isPartTime)
        }
    4. Consolidate Duplicate Conditional Fragements(合并重复的
        条件片段)
           ---在条件表达式的每个分支上有着相同的一段代码
        if(isBook){
            total = price * 0.95;
            send();
        }else{
            total = price * 0.5;
            send();
        }
        分析: 针对这种情况,应该将重复的代码搬移到条件表达式的外面,这样代码才能够更加清
              楚的表明那些东西随条件的变化而变化,那些东西保持不变
        if(isBook){
            total = price * 0.95;
        }else{
            total = price * 0.5;
        }
        send();

    5. Replace Conditional with Polymorphism(以多态取代条件

    表达式)

        如果需要根据对象的不同类型而采取不同的行为,多态使你不需要编写明显的条件表达式。比如重构第一章我们提到的电影分儿童、新片、普通片。这三种片都是电影的不同类型,我们可以定义一个电影的抽象类,然后利用多态的性质,让不同的类型的电影去继承,这样我们就可以去掉多余的条件判断

  • 相关阅读:
    leetCode 移动零 问题记录
    leetCode 加一 问题记录
    leetCode 两个数组的交集 II 问题记录
    leetCode 只出现一次的数字 问题记录
    leetCode 旋转数组 问题记录
    将本地项目上传到git
    RabbitMQ Linux 安装教程
    springboot RabbitMQ 配置
    linux——mysql5.5 安装遇到问题总结&解决方式
    Js预编译 GO和AO活动对象
  • 原文地址:https://www.cnblogs.com/zhangweia/p/2737608.html
Copyright © 2011-2022 走看看