優(yōu)化代碼的幾個小技巧
前言
最近看了《重構(gòu)-改善既有代碼的設(shè)計》這本書,總結(jié)了優(yōu)化代碼的幾個小技巧,給大家分享一下。
提煉函數(shù)(適當(dāng)抽取小函數(shù))
定義
提煉函數(shù)就是將一段代碼放進一個獨立函數(shù)中,并讓函數(shù)名稱解釋該函數(shù)用途。
一個過于冗長的函數(shù)或者一段需要注釋才能讓人理解用途的代碼,可以考慮把它切分成一個功能明確的函數(shù)單元,并定義清晰簡短的函數(shù)名,這樣會讓代碼變得更加優(yōu)雅。
優(yōu)化例子
提煉函數(shù)之前:
private String name;private Vector<Order> orders = new Vector<Order>();public void printOwing() {//print bannerSystem.out.println("****************");System.out.println("*****customer Owes *****");System.out.println("****************");//calculate totalAmountEnumeration env = orders.elements();double totalAmount = 0.0;while (env.hasMoreElements()) {Order order = (Order) env.nextElement();totalAmount += order.getAmout();}//print detailsSystem.out.println("name:" + name);System.out.println("amount:" + totalAmount);}
提煉函數(shù)之后:
以上那段代碼,可以抽成print banner,calculate totalAmount,print details三個功能的單一函數(shù),如下:
private String name;private Vector<Order> orders = new Vector<Order>();public void printOwing() {//print bannerprintBanner();//calculate totalAmountdouble totalAmount = getTotalAmount();//print detailsprintDetail(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);}
內(nèi)聯(lián)函數(shù)(適當(dāng)去除多余函數(shù))
定義
內(nèi)聯(lián)函數(shù)就是在函數(shù)調(diào)用點插入函數(shù)本體,然后移除該函數(shù)。
上一小節(jié)介紹了提煉函數(shù)代碼優(yōu)化方式,以簡短清晰的小函數(shù)為榮。但是呢,小函數(shù)是不是越多越好呢?肯定不是啦,有時候你會遇到某些函數(shù),其內(nèi)部代碼和函數(shù)名稱同樣清晰,這時候呢你可以考慮內(nèi)聯(lián)函數(shù)優(yōu)化一下了。
優(yōu)化例子
內(nèi)聯(lián)函數(shù)之前
int getRating(){return moreThanFiveDeliveries() ? 2 : 1;}boolean moreThanFiveDeliveries(){return numberOfLateDeliveries >5;}
內(nèi)聯(lián)函數(shù)之后
int getRating(){return numberOfLateDeliveries >5 ? 2 : 1;}
內(nèi)聯(lián)臨時變量(去除多余臨時變量)
定義
內(nèi)聯(lián)臨時變量將所有對該變量的引用動作,替換為對它賦值的那個表達式自身。
優(yōu)化例子
內(nèi)聯(lián)臨時變量之前
double basePice = anOrder.basePrice();return basePice >888;
內(nèi)聯(lián)臨時變量之后
return anOrder.basePrice() >888;引入解釋性變量
定義
引入解釋性變量 就是將該復(fù)雜表達式(或其中一部分)的結(jié)果放進一個臨時變量,以此變量名稱來解釋表達式用途。
有些表達式可能非常復(fù)雜難于閱讀,在這種情況下,臨時變量可以幫助你將表達式分解為可讀的形式。
在比較復(fù)雜的條件邏輯中,你可以用引入解釋性變量將每個條件子句提煉出來,以一個良好命名的臨時變量來解釋對應(yīng)條件子句的意義。
優(yōu)化例子
引入解釋性變量之前
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) {......}
以字面常量取代魔法數(shù)
定義
創(chuàng)造一個常量,根據(jù)其意義為它命名,并將上述的字面數(shù)值替換為這個常量。
所謂魔法數(shù)是指擁有特殊意義,卻又不能明確表現(xiàn)出這種意義的數(shù)字。如果你需要在不同的地點引用同一個邏輯數(shù),每當(dāng)該數(shù)字要修改時,會特別頭疼,因為很可能會改漏。而字面常量取代魔法數(shù)可以解決這個頭疼問題。
優(yōu)化例子
以字面常量取代魔法數(shù)之前
double getDiscountPrice(double price){return price * 0.88;}
以字面常量取代魔法數(shù)之后
static final double DISCOUNT_CONSTANT=0.88;double getDiscountPrice(double price){return price * DISCOUNT_CONSTANT;}
用多態(tài)替代switch語句
定義
用多態(tài)替換switch語句 就是利用Java面向?qū)ο蟮亩鄳B(tài)特點,使用state模式來替換switch語句。
優(yōu)化例子
用多態(tài)替換switch語句之前
int getArea() {switch (shape){case SHAPE.CIRCLE:return 3.14 * _r * _r; break;case SHAPE.RECTANGEL;return width *,heigth;}}
用多態(tài)替換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;}}
將過多的參數(shù)對象化
定義
將過多的參數(shù)對象化就是把涉及過多參數(shù)封裝成一個對象傳參。
一個方法有太多傳參時,即難以閱讀又難于維護。尤其針對dubbo遠程調(diào)用這些方法,如果有過多參數(shù),增加或者減少一個參數(shù),都要修改接口,真的坑。如果把這些參數(shù)封裝成一個對象,就很好維護了,不用修改接口。
優(yōu)化例子
將過多的參數(shù)對象化之前:
public int register(String username,String password,Integer age,String phone);將過多的參數(shù)對象化之后:
public int register(RegisterForm from );class RegisterForm{private String username;private String password;private Integer age;private String phone;}
參考與感謝
《重構(gòu)-改善既有代碼的設(shè)計》

騰訊、阿里、滴滴后臺面試題匯總總結(jié) — (含答案)
面試:史上最全多線程面試題 !
最新阿里內(nèi)推Java后端面試題
JVM難學(xué)?那是因為你沒認(rèn)真看完這篇文章

關(guān)注作者微信公眾號 —《JAVA爛豬皮》
了解更多java后端架構(gòu)知識以及最新面試寶典


看完本文記得給作者點贊+在看哦~~~大家的支持,是作者源源不斷出文的動力
