《重構-改善既有代碼設計》讀書筆記-代碼篇


tags: 重構,優雅代碼,讀書筆記

在《重構》一書中,列舉了一些代碼的壞味道,同時以舉例方式講解了重構代碼的一些手法,本文是讀書後的關於如何寫好代碼的筆記,主要包括可讀性、代碼職責、面向對象思惟方面。前端

可讀性

下面是一些提高代碼可讀性的手段、方法。java

Extract Method

當一個方法比較複雜、行數較多時,讀起來使人費解,這時應該抽取出一個個小段代碼的方法,且合理的命名方法,主方法中調用這些方法完成它所作的事情。
固然也不僅是方法複雜時須要抽取方法。後端

優點:
一、經過方法命名,讓主方法調用這些方法就能清晰表達主方法的流程,不須要經過註釋來解釋代碼做用
二、方法小了,代碼簡潔清晰,易於複用數組

引入解釋性變量

代碼邏輯繁雜時,或一些複雜運算,能夠引入變量,並經過對變量的命名來提高可讀性。
如:.net

methodB(ClassX.methodC(methodA(a,  b)))
能夠改成:
    int someValue = ClassX.methodC(methodA(a,  b));
    methodB(someValue);

不要對方法參數從新賦值

code

void method(Object A){
    A = new Object();
}

引入參數對象

當方法參列表較長時,提取對象進行包裝。通常建議參數個數≤3。對象

Rename Method/Class

根據代碼的功能職責合理命名,便於理解blog

用對象取代直接使用數組

用常量取代特殊意義的數字

其目的引入解釋性變量相似繼承

分解複雜條件表達式

將複雜的表達式拆分紅多個簡短的表達式,每個明確其意義。
如:接口

if(a.status != null && a.status = true && date > XXX && date < YYY){
    ......
}
取代爲:
if(validStatus(a.status) && valiadDate(date) ){
    ......
}

能夠更清楚的表達出條件判斷的含義

以特殊檢查取代嵌套的if else

if與else自己表達的是平級的關係,若是是某些特殊罕見條件特殊處理,採用if return的形式予以重視。
這樣可以清晰的體現代碼的主流程,不被一些特殊的處理掩蓋,讀起來更順暢。
如:

boolean flag;
if(conditionX){
    flag = false;
} else{
    if(conditionY){
        flag = false;
    } else{
        do something……
        flag = calculate();
    }
}
return flag;

改成:

if(conditionX) return false;
if(conditionY) return false;

do something……
flag = calculate();
return flag;

以異常取代錯誤碼

服務內部不要採用錯誤碼來表示錯誤,如return -1表示失敗,而應該拋出異常表達
後端與前端服務間的交互可採用errorCode的方式。
關於異常可參考本人另外一篇文章: https://my.oschina.net/hebaod...

代碼職責

咱們常常說面向對象的單一職責原則,大到一個系統、模塊的職責邊界劃分,小到一個類、一個方法的職責。
清晰的劃分類、方法的職責,保持其單1、穩定的功能,能避免往後代碼愈來愈臃腫。

下面是關於代碼職責的處理方法。

Move Method/Field

某個方法不該該屬於這個類或package,移動方法到合適的地方。
某個屬於不該該屬於該對象,移動之。

Extract Class

類愈來愈大,如某個Service的public方法愈來愈多,功能混雜,考慮抽取不一樣的class維護這些方法或屬性。

面向對象的思惟

用多態取代條件表達式

代碼中出現多個if或switch case語句根據不一樣的條件,採起不一樣的行爲時,應該採用多態的思想。
如:

switch(var){
    case v1:
        behavior1();
        break;
    case v2:
        behavior2();
        break;
    defalut:
        behavior3();
}
能夠提煉一個interfa Behavior,根據不一樣var建立不一樣的實現類,最後只須要調用behavior.method便可,也是一種策略模式的體現。

可是,上述說法還沒完全解決switch case的問題,由於要建立不一樣實現類,一種方法是定義一個map存儲映射關係。

Method/Field 上移到超類/下移到子類

採用繼承時,須要區分出某些屬性,方法究竟是共性仍是特性,共性就應該上移到超類中。特性即僅某些子類才具備,應該下移到子類。合理的進行抽象。

提煉超類/接口/子類

發現代碼中有一些共同或相似的行爲屬性時,要考慮提煉超類or接口。定義好抽象的關係,使代碼保持內聚。
關於抽象類與接口參考:https://www.zhihu.com/questio...

組合與繼承的選擇

通常來講組合優先於繼承,組合表達的是has a的關係,繼承表達的是is a的關係。
組合的擴展性更強,且java不支持多繼承。更多關於組合與繼承的討論自行Google吧。

ps:我的blog地址:https://my.oschina.net/hebaod...

相關文章
相關標籤/搜索