重構(gòu) 改善既有代碼的設(shè)計- 讀書筆記

Part 1 實例

  1. 將大的函數(shù)拆分成小函數(shù) (快捷鍵 command+option+M)
    2.變量以及方法命名
    3.函數(shù)應(yīng)該放在它所使用的數(shù)據(jù)所屬的對象內(nèi)(這個方法用了哪些數(shù)據(jù)鸡捐,就放在數(shù)據(jù)對應(yīng)的類下面)
    4.盡量減少臨時變量
    5.多態(tài)取代switch

Part 2 概念
1.重構(gòu)和新增功能不同時進行
2.何時重構(gòu):
1》.隨時重構(gòu),當你想做某個功能,重構(gòu)可以讓這個功能更方便癞揉,或者說做的更好
2》.第三次寫重復(fù)代碼就可以重構(gòu)
3》.添加功能的時候
4》.bug的時候
5》.Code Review的時候

Part 3 代碼的壞味道
1.duplicated code
2.long Method :
解決方式: 1. 提煉 注釋的地方
2. 提煉循環(huán)
3.Large Class
4.Long Parameter List
5.Divergent Change (發(fā)散式變化) ——一個類受多個變化影響
6.Shotgun Surgery (霰彈式變化) ——一種變化影響多個類修改
7.Feature Envy (依戀情節(jié)) —— 一個類使用了多份數(shù)據(jù)渗勘,就放在用的數(shù)據(jù)最多的那個類里
8.Data Clumps (數(shù)據(jù)泥團)
9.Primitive obsession(基本類型偏執(zhí))
10.switch statement
解決方式:多態(tài)
11.Parallel Inheritance Hierarchies (平行繼承體系)—— 當給某個類增加了子類呼胚,必須發(fā)給其他類也增加子類
解決方式:讓一個繼承體系實例引用另一個繼承體系的實例
12.Lazy Class(冗贅類)—— 就是意義不大的類
13.Speculative Generality(夸夸其談未來性)—— 過多設(shè)計導(dǎo)致的東西
14.Temporary Field
15.message Chain(過度耦合的消息鏈)
16.middle man(中間人)—— 過度委托
解決方式:1.去掉過度委托,直接調(diào)用
2. 如果middle man 有其他行為孝扛,可以優(yōu)化成子類

  1. Inappropriate Intimacy (狎昵關(guān)系)——類之間的過于依賴
    18.Alternative Classes with Different Interfaces(異曲同工的類)
    解決方式:1.Extract Superclass
    19.Incomplete Library Class (不完美的庫類)
    20.Data CLass(純稚的數(shù)據(jù)類)
    21.refused bequest(被拒絕的遺贈)
  2. Comments(過多的注釋)
    解決方式:1.好的方法命名代替注釋
    2.introduce assertion

Part 4 關(guān)于測試的一些思考
1.開發(fā)應(yīng)該專注于單元測試,假設(shè)其他包都正常幽崩,對每個包單獨測試
2.當功能測試出現(xiàn)bug的時候苦始,不僅僅應(yīng)該修改bug,還需要用一個單元測試來暴露這個bug
3.尋找邊界條件

Part 6
1.Extract Method

  1. Inline Method
  2. Inline Temp(內(nèi)聯(lián)臨時變量)——用方法代替臨時變量
    eg: 1. if中的條件判斷 應(yīng)該提煉成一個方法
  3. replace temp with query(以查詢?nèi)〈R時變量)
    eg:臨時變量只被賦值一次(如何檢查:1.將目標臨時對象聲明為final)
  4. Introduce Explaining Variable(引入解釋性變量)—— 復(fù)雜的表達式用臨時變量代替(但是也可以用Extract Method,區(qū)別:局部變量使用多慌申,提取成本較大就用Introduce Explaining Variable)
  5. Split Temporary Variable(分解臨時變量)—— 除了循環(huán)用的臨時變量陌选,一般的臨時變量應(yīng)該只被賦值一次,如果有多次蹄溉,需要判斷意義是否一樣咨油,不一樣應(yīng)該用一個新的臨時變量去裝載
  6. Remove Assignments to Parameters(移除對參數(shù)的賦值)—— 用臨時變量去裝這個賦值
  7. Replace Method with Method Object —— 把一個復(fù)雜函數(shù)(用了太多臨時變量的函數(shù))提取成一個class< A class >, 把所有臨時變量都放入final 字段里柒爵。然后再原來方法調(diào)用的地方役电,使用委托的方式,讓新的類的方法被調(diào)用<eg:new A().getContant()>, 然后就可以在A class 里面進行Extract Method
  8. Substitute Algorithm(替換算法)—— 將復(fù)雜的算法 用簡單的算法餐弱,更加易讀的算法代替

Part 7

  1. move Method—— 當一個類的行為過多宴霸,或者一個類和另外一個類高度耦合,就可以使用這個方式
  2. move field
  3. Extract Class—— 根據(jù)不同的責(zé)任劃分類
  4. Inline Class
  5. Hide delegate(隱藏委托關(guān)系)—— 對外部隱藏某個調(diào)用關(guān)系
  6. Remove Middle Man —— 移除過多的委托關(guān)系(出現(xiàn)大量委托關(guān)系的時候膏蚓,可以直接暴露相關(guān)對象)
  7. Introduce Foreign Method(引入外加函數(shù))—— 當出現(xiàn)大量對某個函數(shù)的調(diào)用使用同一個值瓢谢,且參數(shù)較多的情況,可以將這個調(diào)用過程Extract Method 驮瞧,這個函數(shù)叫做被調(diào)用函數(shù)的外加函數(shù)
  8. Introduce Local extension(引入本地擴展)—— 當 外加函數(shù)較多的時候氓扛,應(yīng)該使用Introduce Local extension,有2種做法:① 子類 繼承论笔,super() ② 包裝類 使用 委托

Part 8

  1. Self Encapsulate Field(自封裝字段)—— 在類內(nèi)部也使用使用get set方法獲取字段的值
  2. Replace Data Value with Object(以對象取代數(shù)據(jù)值)—— 數(shù)據(jù)對象復(fù)雜采郎,或者數(shù)據(jù)關(guān)系較多,應(yīng)該封裝成一個對象
  3. Change Value to Reference (將值對象改為引用對象)
  4. Change Reference to Value (將引用對象改為值對象)
  5. Replace Array with Object —— 數(shù)組應(yīng)該用于“以某種順序容納一組相似對象”狂魔,如果涉及到一個東西的多個屬性蒜埋,多個對象 就應(yīng)該改為object
  6. Duplicate Observe Data (復(fù)制被監(jiān)視的數(shù)據(jù))
  7. Change Unidirectional Association to Bidirectional(將單項關(guān)聯(lián)改為雙向關(guān)聯(lián))
  8. Change Bidirectional Association to Unidirectional(將雙向關(guān)聯(lián)改為單項關(guān)聯(lián))
  9. Replace Magic Number with Symbolic Constant(用字面常亮取代魔法數(shù))—— 就是用 static final + 類型+ 名稱 = 魔法數(shù)
  10. Encapsulate Field(封裝字段)—— 把public 字段設(shè)置為private,使用get set函數(shù)公開出去
  11. Encapsulate Collection(封裝集合)—— 不要把整個集合公開出去最楷,只是把需要公開的 add 方法公開出去整份,比如 新增集合里的一個元素待错,對外的應(yīng)該只有
 public void addCourse(object obj){
    courses.add(obj);
}

只會把obj 扔出去,

  1. Replace Record with Data Class(以數(shù)據(jù)類代替記錄)
  2. Replace Type Code with Class(以類取代類型碼)
  3. Replace Type Code with Subclasses —— 面對swich 這種判斷需要的就可以把type code 使用子類來重構(gòu)
  4. Replace Type Code with State/Strategy
  5. Replace Subclass with Fields(用字段取代子類)—— 子類中如只有一個常量函數(shù)烈评,那么久沒有必要用子類火俄。可以直接用字段來代替

Part 9

  1. Decompose Conditional(分解條件表達式)—— 把 if讲冠,then瓜客, else中的條件語句提取出來
  2. Consolidate Condition Expression(合并條件表達式)—— 就是把結(jié)果一致的條件放在一起
  3. Consolidate Duplicate Conditional Fragments(合并重復(fù)的條件片段)—— 有共同的執(zhí)行提取出來
  4. Remove Control Flag—— 用 break or continue 代替
  5. Replace Nested Conditional with Guard Clauses(以衛(wèi)語句取代嵌套條件表達式)—— 衛(wèi)語句:單獨的某個檢查,如果為真立刻返回竿开。檢查提前谱仪,對特殊情況單獨處理
  6. Replace Conditional with Polymorphism(以多態(tài)取代條件表達式)—— 繼承代替switch
  7. Introduce Null Object (引入null對象)—— 把返回null的地方用一個空對象代替, 這個空對象可以處理默認值
  8. Introduce Assertion(引入斷言)—— 作為調(diào)試和輔助開發(fā),提前判斷結(jié)果德迹,最后會刪除

Part 10

  1. Rename Method —— 良好的命名方式
  2. Add Parameter
  3. Remove Parameter
  4. Separate Query from Modifier (分離查詢函數(shù)和修改函數(shù))—— 把修改對象的方法和僅是查詢數(shù)據(jù)的方法分開
  5. Parameterize Method (令函數(shù)攜帶參數(shù))—— 用參數(shù)減少重復(fù)代碼
  6. Replace Parameter with Explicit Method (用明確函數(shù)取代參數(shù))—— 用多個函數(shù)取代 帶有多個意義的單個函數(shù)芽卿,當某個函數(shù)出現(xiàn)大量if else類似的判斷就需要用這種方式重構(gòu)
  7. Preserve Whole Object(保持對象完整)—— 當某個函數(shù)大量用到調(diào)用方的某個對象的參數(shù)的時候,應(yīng)該使用對象胳搞,而不是拆解出來的多個值
  8. Replace Parameter with Methods(用函數(shù)取代參數(shù))—— 當某個參數(shù)是從其他函數(shù)取得的時候,應(yīng)該直接在方法函數(shù)內(nèi)部自行調(diào)用称杨,不要從參數(shù)傳入
  9. Introduce Parameter Object(引入?yún)?shù)對象)—— 當某一組參數(shù)被大量傳遞肌毅,應(yīng)該用個類把他們包裹起來傳遞
  10. Remove Setting Method (移除設(shè)值函數(shù))—— 如果不對外公開set方法,該值僅通過構(gòu)造方法設(shè)值有效姑原, 就移除set參數(shù)
  11. Hide Method—— 不必要的函數(shù)設(shè)置為private
  12. Replace Constructor with Factory Method(工廠模式代替構(gòu)造函數(shù))—— Class.forName
  13. Encapsulate Downcast(封裝向下轉(zhuǎn)型)—— 將向下轉(zhuǎn)型的動作移到方法里
  14. Replace Error Code with Exception(用異常取代錯誤碼)
  15. Replace Exception with Test(用測試取代異常)—— 異常應(yīng)該是用于罕見悬而,異常的行為,而不是使用在條件檢查的地方锭汛,把某些正常行為的處理笨奠,使用條件語句放在前面

Part 11

  1. Pull Up Field(字段上移)—— 子類公有的字段可以移到超類
  2. Pull Up Method(函數(shù)上移)—— 子類中完全相同結(jié)果的函數(shù)可以移到超類
  3. Pull Up Constructor Body (構(gòu)造函數(shù)本體上移) —— 子類中相同的構(gòu)造函數(shù)移動到超類
  4. Push Down Method (函數(shù)下移)—— 當超類中的某個函數(shù)只于部分子類相關(guān)
  5. Push Down Field(字段下移)—— 當超類中某個字段只于特定子類相關(guān)
  6. Extract Subclass (提煉子類)—— 某些特性 只被部分實例使用,應(yīng)該移到子類中去
  7. Extract Superclass (提煉超類)—— 兩個類有相似特性類唤殴,可以提煉出公共部分般婆,移到超類里去
  8. Extract Interface (提煉接口)—— 多個類提供相同功能的時候(比如租借接口,然后電腦和磁帶實現(xiàn)該接口朵逝,提供不同的計算方式)
  9. Collapse Hierarchy (折疊繼承體系)—— 超類和子類區(qū)別不大的時候蔚袍,應(yīng)該合并
  10. Form Template Method (塑造模板函數(shù))—— 就是多個類流程一致,但是每個流程實現(xiàn)方式不一致的時候配名,用 ’模板方法模式‘ 代替(父類規(guī)定一個invoke 函數(shù)啤咽,和其他抽象函數(shù),子類實現(xiàn)不同的抽象函數(shù))
  11. Replace Inheritance with Delegate(委托取代繼承)—— 子類只使用超類中的一部分數(shù)據(jù)渠脉,而且不需要繼承的數(shù)據(jù)
  12. Replace Delegate with Inheritance(繼承取代委托)—— 兩個類之間屬于委托關(guān)系宇整,但是大部分是簡單的委托函數(shù),類似直接調(diào)用被委托的類的函數(shù)(但是如果沒有使用到受托類的所有函數(shù)就應(yīng)不應(yīng)該使用該方法)

Part 12

  1. Tease Apart Inheritance(梳理并分解繼承體系)
  2. Convert Procedural Design to Objects(將過程化設(shè)計轉(zhuǎn)為對象設(shè)計)
  3. Separate Domain from Presentation (將領(lǐng)域和表述/顯示分離)
  4. Extract Hierarchy (提煉繼承體系)
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末芋膘,一起剝皮案震驚了整個濱河市鳞青,隨后出現(xiàn)的幾起案子涩哟,更是在濱河造成了極大的恐慌,老刑警劉巖盼玄,帶你破解...
    沈念sama閱讀 206,214評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件贴彼,死亡現(xiàn)場離奇詭異,居然都是意外死亡埃儿,警方通過查閱死者的電腦和手機器仗,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,307評論 2 382
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來童番,“玉大人精钮,你說我怎么就攤上這事√旮” “怎么了轨香?”我有些...
    開封第一講書人閱讀 152,543評論 0 341
  • 文/不壞的土叔 我叫張陵,是天一觀的道長幼东。 經(jīng)常有香客問我臂容,道長,這世上最難降的妖魔是什么根蟹? 我笑而不...
    開封第一講書人閱讀 55,221評論 1 279
  • 正文 為了忘掉前任脓杉,我火速辦了婚禮,結(jié)果婚禮上简逮,老公的妹妹穿的比我還像新娘球散。我一直安慰自己,他們只是感情好散庶,可當我...
    茶點故事閱讀 64,224評論 5 371
  • 文/花漫 我一把揭開白布蕉堰。 她就那樣靜靜地躺著,像睡著了一般悲龟。 火紅的嫁衣襯著肌膚如雪屋讶。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,007評論 1 284
  • 那天躲舌,我揣著相機與錄音丑婿,去河邊找鬼。 笑死没卸,一個胖子當著我的面吹牛羹奉,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播约计,決...
    沈念sama閱讀 38,313評論 3 399
  • 文/蒼蘭香墨 我猛地睜開眼诀拭,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了煤蚌?” 一聲冷哼從身側(cè)響起耕挨,我...
    開封第一講書人閱讀 36,956評論 0 259
  • 序言:老撾萬榮一對情侶失蹤细卧,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后筒占,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體贪庙,經(jīng)...
    沈念sama閱讀 43,441評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 35,925評論 2 323
  • 正文 我和宋清朗相戀三年翰苫,在試婚紗的時候發(fā)現(xiàn)自己被綠了止邮。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,018評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡奏窑,死狀恐怖导披,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情埃唯,我是刑警寧澤撩匕,帶...
    沈念sama閱讀 33,685評論 4 322
  • 正文 年R本政府宣布,位于F島的核電站墨叛,受9級特大地震影響止毕,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜巍实,卻給世界環(huán)境...
    茶點故事閱讀 39,234評論 3 307
  • 文/蒙蒙 一滓技、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧棚潦,春花似錦、人聲如沸膝昆。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,240評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽荚孵。三九已至妹窖,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間收叶,已是汗流浹背骄呼。 一陣腳步聲響...
    開封第一講書人閱讀 31,464評論 1 261
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留判没,地道東北人蜓萄。 一個月前我還...
    沈念sama閱讀 45,467評論 2 352
  • 正文 我出身青樓,卻偏偏與公主長得像澄峰,于是被迫代替她去往敵國和親嫉沽。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 42,762評論 2 345