優化代碼的幾個小技巧

前言

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

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

定義

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

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

優化例子

提煉函數以前:優化

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);
    }
複製代碼

提煉函數以後:ui

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

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);
    }

複製代碼

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

定義

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

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

優化例子

內聯函數以前orm

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

內聯函數以後cdn

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;
 }
複製代碼

參考與感謝

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

我的公衆號

  • 若是你是個愛學習的好孩子,能夠關注我公衆號,一塊兒學習討論。
  • 若是你以爲本文有哪些不正確的地方,能夠評論,也能夠關注我公衆號,私聊我,你們一塊兒學習進步哈。
相關文章
相關標籤/搜索