zoukankan      html  css  js  c++  java
  • 《重构-改善既有代码的设计》读书笔记

    重构

    以查询取代临时变量

    临时变量的问题在于:它们是暂时的,而且只能在所属函数内使用。由于临时变量只能在所属函数内可见,所以它们会趋势你写出更长的函数,因为只有这样你猜可以访问到所需要的临时变量,如果把临时变量替换为一个查询,那么同一个类中的所有函数都可以获得这份信息。

    范例

    double getPrice() {
       int basePrice = number * itemPrice;
       double discountFactor;
       if (basePrice > 1000) discountFactor = 0.95;
       else discountFactor = 0.98;
       return basePrice * discountFactor;
    }
    

    将临时变量声明为final

    double getPrice() {
       final int basePrice = number * itemPrice;
       final double discountFactor;
       if (basePrice > 1000) discountFactor = 0.95;
       else discountFactor = 0.98;
       return basePrice * discountFactor;
    }
    

    把赋值动作的右侧表达式提炼出来

    double getPrice() {
       final int basePrice = getBasePrice();
       final double discountFactor = getDiscount();
       return getBasePrice() * discountFactor;
    }
    
    int getBasePrice() {
        return number * itemPrice;
    }
    
    double getDiscount() {
        if (getBasePrice() > 1000) return  0.95;
        else return  0.98;
    }
    

    最后

    double getPrice() {
       final int basePrice = getBasePrice();
       
       return getBasePrice() * getDiscount();
    }
    
    int getBasePrice() {
        return number * itemPrice;
    }
    
    double getDiscount() {
        if (getBasePrice() > 1000) return  0.95;
        else return  0.98;
    }
    

    引入解释性变量

    你有一个复杂的表达式,将该复杂的表达式(或其中一部分)的结果放进一个临时变量,以此变量名称来解释表达式的用途。

    if ((platform.toUpperCase().indexOf("MAC") > -1) &&
        (browser.toUpperCase().indexOf("IE") > -1)  &&
        wasInitialized() && resize > 0)
    {
        // do something
    }
    

    可以重构为:

    final boolean isMacOS = platform.toUpperCase().indexOf("MAC") > -1;
    final boolean isIEBrowser = platform.toUpperCase().indexOf("IE") > -1
    final boolean wasResized = resize > 0;
    if (isMacOS && isIEBrowser && wasInitialized() && wasResized)
    {
        // do something
    }
    

    分解临时变量

    如果你的程序有某个临时变量赋值超过一次,它既不是循环变量也不是结果收集变量,这就意味着这个临时变量在函数中承担了一个以上的责任,如果临时变量承担多个责任,就应该针对每次赋值,创造一个独立,对应的临时变量。

    double temp = 2 * (height + width);
    System.out.println(temp);
    temp = height * width;
    System.out.println(temp);
    

    应该改写成:

    final double perimeter = 2 * (height + width);
    System.out.println(perimeter);
    final double area = height * width;
    System.out.println(area);
    

    以函数对象取代函数

    将这个函数放进一个单独的对象中,如此一来局部变量就成了对象内的字段,然后你可以在同一个对象中将这个大型函数分解为多个小型函数

    class Account {
       int gamma(int inputVal, int quantity, int yearToDate) {
            int importantValue1 = (inputVal * quantity) + delta();
            int importantValue2 = (inputVal * yearToDate) + 100;
            if ....
            ....
            ....
            return importantValue3 - 2 * importantValue1;
       }    
    }
    

    第一步:把这个函数变为一个函数对象,并加入一个构造函数

    class Gamma {
        private final Account account;
        private int inputVal;
        private int quantity;
        private int yearToDate;
        private int importantValue1;
        private int importantValue2;
        pirvate int importantValue3;
        
        Gamma(Account account, int inputVal, int quantity, int yearToDate) {
            this.xx = xx
            ...
            ...
            ...
        }
    }
    

    现在可以把原本的函数搬到compute()中了,

    int compute() {
        int importantValue1 = (inputVal * quantity) + account.delta();
        int importantValue2 = (inputVal * yearToDate) + 100;
        if ....
        ....
        ....
        return importantValue3 - 2 * importantValue1;
    }
    

    然后,我们修改旧的函数:

    int gamma(int inputVal, int quantity, int yearToDate) {
        return new Gamma(this, inputVal, quantity, yearToDate).compute();
    }    
    
  • 相关阅读:
    TypeScript 函数
    单链表 C++
    测试用例概念 原则
    TypeScript 类
    TypeScript 接口
    Cellection
    面向对象
    反射
    B树
    无权无向图
  • 原文地址:https://www.cnblogs.com/greyzeng/p/6181418.html
Copyright © 2011-2022 走看看