優化代碼的幾個小技巧

前言

最近看了《重構-改善既有代碼的設計》這本書,總結了優化代碼的幾個小技巧,給大家分享一下。

提煉函數(適當抽取小函數)

定義

提煉函數就是將一段代碼放進一個獨立函數中,並讓函數名稱解釋該函數用途。

一個過於冗長的函數或者一段需要註釋才能讓人理解用途的代碼,可以考慮把它切分成一個功能明確的函數單元,並定義清晰簡短的函數名,這樣會讓代碼變得更加優雅。

優化例子

提煉函數之前:

    private String name;	
    private Vector<Order> orders = new Vector<Order>();	
    public void printOwing() {	
        //print banner	
        System.out.println("****************");	
        System.out.println("*****customer Owes *****");	
        System.out.println("****************");	
        //calculate totalAmount	
        Enumeration env = orders.elements();	
        double totalAmount = 0.0;	
        while (env.hasMoreElements()) {	
            Order order = (Order) env.nextElement();	
            totalAmount += order.getAmout();	
        }	
        //print details	
        System.out.println("name:" + name);	
        System.out.println("amount:" + totalAmount);	
    }

提煉函數之後:

以上那段代碼,可以抽成print banner,calculate totalAmount,print details三個功能的單一函數,如下:

    private String name;	
    private Vector<Order> orders = new Vector<Order>();	
    public void printOwing() {	
        //print banner	
        printBanner();	
        //calculate totalAmount	
        double totalAmount = getTotalAmount();	
        //print details	
        printDetail(totalAmount);	
    }	
    void printBanner(){	
        System.out.println("****************");	
        System.out.println("*****customer Owes *****");	
        System.out.println("****************");	
    }	
    double getTotalAmount(){	
        Enumeration env = orders.elements();	
        double totalAmount = 0.0;	
        while (env.hasMoreElements()) {	
            Order order = (Order) env.nextElement();	
            totalAmount += order.getAmout();	
        }	
        return totalAmount;	
    }	
    void printDetail(double totalAmount){	
        System.out.println("name:" + name);	
        System.out.println("amount:" + totalAmount);	
    }

內聯函數(適當去除多餘函數)

定義

內聯函數就是在函數調用點插入函數本體,然後移除該函數。

上一小節介紹了提煉函數代碼優化方式,以簡短清晰的小函數爲榮。但是呢,小函數是不是越多越好呢?肯定不是啦,有時候你會遇到某些函數,其內部代碼和函數名稱同樣清晰,這時候呢你可以考慮內聯函數優化一下了。

優化例子

內聯函數之前

    int getRating(){	
        return moreThanFiveDeliveries() ? 2 : 1;	
    }	
    boolean moreThanFiveDeliveries(){	
        return numberOfLateDeliveries >5;	
    }

內聯函數之後

  int getRating(){	
        return numberOfLateDeliveries >5 ? 2 : 1;	
 }

內聯臨時變量(去除多餘臨時變量)

定義

內聯臨時變量將所有對該變量的引用動作,替換爲對它賦值的那個表達式自身。

優化例子

內聯臨時變量之前

double basePice = anOrder.basePrice();	
return basePice >888;

內聯臨時變量之後

 return anOrder.basePrice() >888;

引入解釋性變量

定義

引入解釋性變量 就是將該複雜表達式(或其中一部分)的結果放進一個臨時變量,以此變量名稱來解釋表達式用途。

有些表達式可能非常複雜難於閱讀,在這種情況下,臨時變量可以幫助你將表達式分解爲可讀的形式。

在比較複雜的條件邏輯中,你可以用引入解釋性變量將每個條件子句提煉出來,以一個良好命名的臨時變量來解釋對應條件子句的意義。

優化例子

引入解釋性變量之前

if ((platform.toUpperCase().indexOf("mac") > -1) &&	
    (brower.toUpperCase().indexOf("ie") > -1) &&	
    wasInitializes() && resize > 0) {	
        ......	
    }

引入解釋性變量之後

final boolean isMacOS = platform.toUpperCase().indexOf("mac") > -1;	
final boolean isIEBrowser = brower.toUpperCase().indexOf("ie") > -1;	
final boolean wasResized = resize > 0;	
if (isMacOS && isIEBrowser && wasInitializes() && wasResized) {	
    ......	
}

以字面常量取代魔法數

定義

創造一個常量,根據其意義爲它命名,並將上述的字面數值替換爲這個常量。

所謂魔法數是指擁有特殊意義,卻又不能明確表現出這種意義的數字。如果你需要在不同的地點引用同一個邏輯數,每當該數字要修改時,會特別頭疼,因爲很可能會改漏。而字面常量取代魔法數可以解決這個頭疼問題。

優化例子

以字面常量取代魔法數之前

double getDiscountPrice(double price){	
       return price * 0.88;	
 }

以字面常量取代魔法數之後

 static final double DISCOUNT_CONSTANT=0.88;	
 double getDiscountPrice(double price){	
     return price * DISCOUNT_CONSTANT;	
 }

用多態替代switch語句

定義

用多態替換switch語句 就是利用Java面向對象的多態特點,使用state模式來替換switch語句。

優化例子

用多態替換switch語句之前

 int getArea() {	
        switch (shape){	
        case SHAPE.CIRCLE:	
        return 3.14 * _r * _r; break;	
        case SHAPE.RECTANGEL;	
        return width *,heigth;	
        }	
    }

用多態替換switch語句之後

 class Shape {	
        int getArea(){};	
    }	
    class Circle extends Shape {	
        int getArea() {	
            return 3.14 * r * r; 	
        }	
    }	
    class Rectangel extends Shape {	
        int getArea() {	
            return width * heigth;	
        }	
    }

將過多的參數對象化

定義

將過多的參數對象化就是把涉及過多參數封裝成一個對象傳參。

一個方法有太多傳參時,即難以閱讀又難於維護。尤其針對dubbo遠程調用這些方法,如果有過多參數,增加或者減少一個參數,都要修改接口,真的坑。如果把這些參數封裝成一個對象,就很好維護了,不用修改接口。

優化例子

將過多的參數對象化之前:

public int register(String username,String password,Integer age,String phone);

將過多的參數對象化之後:

 public int register(RegisterForm from );	
 class RegisterForm{	
     private String username;	
     private String password;	
     private Integer age;	
     private String phone;	
 }

參考與感謝

  • 《重構-改善既有代碼的設計》

個人公衆號

640?wx_fmt=jpeg

  • 如果你是個愛學習的好孩子,可以關注我公衆號,一起學習討論。

  • 如果你覺得本文有哪些不正確的地方,可以評論,也可以關注我公衆號,私聊我,大家一起學習進步哈。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章