摘要:重構(gòu)在不改變代碼的外在的行為的前提下對代碼進行修改最大限度的減少錯誤的幾率本質(zhì)上,就是代碼寫好之后修改它的設(shè)計。重構(gòu)可以深入理解代碼并且?guī)椭业健M瑫r重構(gòu)可以減少引入的機率,方便日后擴展。平行繼承目的在于消除類之間的重復代碼。
重構(gòu) (refactoring) 在不改變代碼的外在的行為的前提下 對代碼進行修改最大限度的減少錯誤的幾率 本質(zhì)上, 就是代碼寫好之后 修改它的設(shè)計。
1,書中開始用一個例子簡單闡釋為什么要重構(gòu),以及重構(gòu)的好處
- 如果沒有重構(gòu),程序就會腐敗變質(zhì),程序逐漸失去自己的結(jié)構(gòu),
越來越難通過讀源碼理解設(shè)計,不良重復的代碼不便于后來的修改和閱讀。
- 重構(gòu)可以深入理解代碼并且?guī)椭业絙ug。
同時重構(gòu)可以減少bug引入的機率,方便日后擴展。提高可理解性, 降低修改成本。
- 提高編程的速度,良好的設(shè)計師快速開發(fā)的根本(阻止代碼腐敗,
提高質(zhì)量,從而提高開發(fā)速度)。 sum:容易閱讀,所有邏輯都只在唯一的地點指定,新的改動不會影響過去的功能, 盡可能的表達條件邏輯。
----------
1.2,重構(gòu)的第一步就是建立一個有效的測試機制,好的測試機制可以幫助重構(gòu)
1.3,針對案例中的customer類的函數(shù)statement進行分析,這個函數(shù)太長,需要分解,拆分,因為簡單的代碼塊容易管理。
作者將這個statement函數(shù)里面的根據(jù)電影的類型返回不同的價格的方法,提煉出來,代碼簡潔易懂
關(guān)于函數(shù)的名稱的命名,作者總結(jié)道,只有寫出人類容易理解的代碼 才是優(yōu)秀的代碼。
函數(shù)位置:函數(shù)應該放在它使用的數(shù)據(jù)的所屬對象內(nèi),所以作者舉例說明那個customer中的statement函數(shù)根據(jù)不同類的作用做了拆分,比如獲取電影的價錢和積分數(shù)放在租賃類中,獲取總電影價以及總積分放在Customer類中,這樣邏輯清晰。
2,重構(gòu)原則
2.1,什么時候重構(gòu) - 添加新功能是重構(gòu) - 修復bug時重構(gòu) - 評審代碼是重構(gòu)(結(jié)對編程)
重構(gòu)小技巧:
- 允許邏輯共享 - 分開解釋意圖或?qū)崿F(xiàn) - 隔離變化 例如一個類需要在2個地方使用,可以使用子類來處理變化 4)封裝條件邏輯 2.2, 重構(gòu)與設(shè)計 前提簡單可行的設(shè)計(不一定要完全正確), 重構(gòu)可以預先取代設(shè)計,先把功能做好 然后重構(gòu) “極限編程” 支持這種觀點,證明這種方法可行 2.3,重構(gòu)與性能 時間預算 持續(xù)關(guān)注法(深度理解代碼,并且知道哪些地方耗費時間) 性能優(yōu)化案例: 大字符串操作耗費性能? 字符串緩存起來 - 改用文件流處理 - 多處理器計算機,多線程 系統(tǒng)從運算1000個小時 到 2個小時的飛速提升
3,代碼壞味道
重復代碼 - 同一個類 2個函數(shù)有相同的表達式 - 兄弟子類有相同的表達式 - 2個獨立的類有相同的代碼 3.2 函數(shù)過長 分解函數(shù)的原則:每當感覺需要注釋說明點什么的時候,我們需要把需要說明的東西寫到一個獨立的函數(shù)中,并以其用途來命名。如果代碼前面有一條注釋,就說明這個地方需要提煉出一個函數(shù)。 條件表達式(多個if else 改成三元表達式 Decompose Conditional) 和循環(huán)也是提煉的信號, 循環(huán)可以提煉到一個多帶帶的函數(shù)中。 3.3 過大的類 --解決重復代碼的問題 3.4 過長的參數(shù)列,建議使用參數(shù)對象,傳遞一個參數(shù)。 3.5 發(fā)散式變化(一個類受到多種變化的影響),散彈式修改 一個變化引發(fā)多個類修改 解決經(jīng)常被修改的類,將經(jīng)常需要修改的變量字段提煉到一個獨立的類。 3.6 依戀情節(jié) 數(shù)據(jù)和數(shù)據(jù)操作包裝在一起 原則:將總是一起發(fā)生變化的東西放在一起。 3.7 數(shù)據(jù)泥團 類中有相同的屬性 函數(shù)中有類似的參數(shù) 刪除一個不影響這個類或者函數(shù)的意義,建議拆分新對象 減少字段或者參數(shù)的個數(shù) 3.8,switch statement 大多情況下 出現(xiàn)switch語句 就應該考慮多態(tài)來替換,這樣的switch需要提煉到一個獨立的函數(shù)并且將它放到需要處理的類中。 3.9 平行繼承 目的在于消除類之間的重復代碼。 3.10 冗贅類 無用的代碼類。 3.11 暫時使用的字段 只有執(zhí)行某個代碼塊才有意義的字段 抽到一個獨立的類中 3.12 過多的注釋 試圖用函數(shù)提煉代碼,刪除注釋
4,構(gòu)建測試體系
意義:一套測試就是一個強大的bug監(jiān)聽器 能夠大大減少bug查找時間 建立一個獨立的類用于測試并且在框架中運用它,使測試工作更加輕松 4.1 Junit 測試框架的運用 每收到一個bug,先寫一個單元測試來暴露bug,考慮可能出錯的邊界條件,把測試的重點集中在那
5 重構(gòu)列表
6.重構(gòu)函數(shù)
重構(gòu)的大部分集中在函數(shù)的重構(gòu),參數(shù)的重構(gòu) 內(nèi)聯(lián)函數(shù) 去除間接層 1,不要對參數(shù)賦值(Java 1.1 允許將參數(shù)定義為final)。 2,如果臨時變量被多次賦值,應該分解多個獨立的臨時變量 3,分析臨時變量是否被公用,把這個臨時變量提煉到一個函數(shù)中(Replace temp with query) 4,臨時變量用于分解復雜的表達式 5,替換算法,將比較復雜的算法替換成簡單的 易懂的(或者將大的算法分成小部分 易于理解,然后尋找小算法的替換方案)
7,對象之間的搬移特性
1,函數(shù)搬移 -- 一個類函數(shù)過多 或者 函數(shù)依賴的類比較多 考慮這個函數(shù)與哪個類接觸較多來決定搬移路徑。 2,字段搬移 -- 隨著業(yè)務的發(fā)展,發(fā)現(xiàn)一個類中的一個字段被多個函數(shù)或者類共同使用,考慮搬移這個字段或者可見度的改變(將這個字段變成public) 3,提煉類 -- 隨著業(yè)務的發(fā)展 一個類中有太多的函數(shù)和字段 考慮把類似的字段和函數(shù)搬移出去。 4,內(nèi)聯(lián)化 -- 將一些不獨立承擔任務的類塞到另外一個獨立類中,這種類稱為萎縮類。 5, 委托關(guān)系,簡單理解為封裝函數(shù),便于日后修改變得容易。
8,重新組織數(shù)據(jù)
1,自封裝字段 簡單理解就是將這個字段需要轉(zhuǎn)換的值通過函數(shù)的方式表達 getBussinessVal(); 2,以對象取代數(shù)據(jù)值 一個字段存在多種數(shù)據(jù)與行為一起使用才有意義時 建議將字段變成對象。 3,將值對象(數(shù)值)變成引用用對象(物體) 同一個對象被多個其他的類同時用到,比如 數(shù)據(jù)庫連接,這個時候我們用工廠模式 進行復用來重構(gòu)。 4,以對象取代數(shù)組, 方便用戶記憶 5,將系統(tǒng)的魔法數(shù)定義為常量 static final double WEIGHT_CONSTANT = 9.18; 6, 封裝字段,將行為和意義類似的字段封裝起來定義為private 提供public的訪問函數(shù) 7,封裝對象關(guān)聯(lián)的集合,和數(shù)組 根據(jù)業(yè)務邏輯封裝 list.add 改為emp.addEmp(); 將類似操作對象的集合統(tǒng)一集中到這個類中 8,運用多態(tài)繼承取代switch,將涉及到switch的類型碼判斷 統(tǒng)一移動對象類里面處理 9,子類中不應該有常量 如果有在超類中申明抽象類 在子類實現(xiàn) 返回不同值
9,簡化條件表達式
1,分解合并條件表達式 - 利用函數(shù)的方法 將多個判斷條件根據(jù)業(yè)務邏輯封裝成獨立函數(shù),用功能目的來命名,然后調(diào)用函數(shù)判斷 例如 if (notData(params)){...} else {...} 2,合并上下重復的條件判斷 3,循環(huán)邏輯用break 和 return 取代控制指標 比如 while(a10,簡化函數(shù)調(diào)用
1,修改函數(shù)的名稱 -- 首先考慮給這個函數(shù)寫上一句怎樣的注釋,然后想辦法將注釋變成函數(shù)的名稱
2,將查詢函數(shù)和修改函數(shù)分離 如果發(fā)現(xiàn)一個函數(shù)有返回值又有副作用的函數(shù) 優(yōu)化方法,將查詢到的值緩存到某個字段中,這樣后續(xù)的查詢就可以加快速度
3,將2個類似的函數(shù) 通過函數(shù)合并 減少代碼量
4,保持函數(shù)參數(shù)傳遞的對象完整 比如 in a = sumANums(b).getM(); 直接傳遞真?zhèn)€對象 plan.setCountNums(sumANums(b));
5, 盡量減少參數(shù)個數(shù),建議傳遞一個對象作為參數(shù)
6,將一些經(jīng)常一起傳遞的參數(shù)作為一個參數(shù)對象傳遞
7,移除設(shè)值函數(shù),發(fā)現(xiàn)系統(tǒng)中有一個字段初始化被賦值一次然后一直不變 移除這個字段,并且直接修改這個字段為final
8,隱藏函數(shù),更加這個函數(shù)是否被調(diào)用的次數(shù)判斷是否設(shè)置某些值為private 和 public,盡可能的降低函數(shù)的可見度
9,以工廠函數(shù)取代構(gòu)造函數(shù) 解決switch的類型碼的判斷例如:private int _type; static final int A = 1; static final int B = 2; Employee(int type) {_type = type;}static Employee create(int type) { return new Employee(type)}11, 處理概括關(guān)系
1,字段上移 兩個類擁有相同的字段 將該字段移至超類 2,函數(shù)上移,兩個函數(shù),在各個子類中產(chǎn)生完全相同的結(jié)果,將該函數(shù)移至超類 3,構(gòu)造函數(shù)上移,在子類的構(gòu)造函數(shù)中調(diào)用它 4,函數(shù)、字段下移,相反 5,提煉接口,將兩個接口相同的子集提煉到一個獨立的接口中 6,以委托取代繼承 隨著義務的發(fā)展 超類中的一些函數(shù)你不需要,這時需要新建一個子類委托繼承你需要的函數(shù),然后再繼承你需要的類12,大型重構(gòu) 關(guān)于繼承的重構(gòu)
13,重構(gòu) 復用與現(xiàn)實
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://m.specialneedsforspecialkids.com/yun/67924.html
摘要:重構(gòu)改善既有代碼設(shè)計動詞使用一系列重構(gòu)手法,在不改變軟件可觀察行為的前提下,調(diào)整其結(jié)構(gòu)。修補錯誤時重構(gòu)代碼時重構(gòu)怎么重構(gòu)關(guān)于代碼的重構(gòu)技巧參考重構(gòu)改善既有代碼設(shè)計讀書筆記代碼篇個人博客 重構(gòu)定義 名詞 對軟件內(nèi)部結(jié)構(gòu)的一種調(diào)整,目的是在不改變軟件可觀察行為的前提下,提高其可理解性,降低其修改成本。——《重構(gòu)-改善既有代碼設(shè)計》 動詞 使用一系列重構(gòu)手法,在不改變軟件可觀察行為的前提下,...
摘要:哪吒社區(qū)技能樹打卡打卡貼函數(shù)式接口簡介領(lǐng)域優(yōu)質(zhì)創(chuàng)作者哪吒公眾號作者架構(gòu)師奮斗者掃描主頁左側(cè)二維碼,加入群聊,一起學習一起進步歡迎點贊收藏留言前情提要無意間聽到領(lǐng)導們的談話,現(xiàn)在公司的現(xiàn)狀是碼農(nóng)太多,但能獨立帶隊的人太少,簡而言之,不缺干 ? 哪吒社區(qū)Java技能樹打卡?【打卡貼 day2...
摘要:什么是重構(gòu)列表重構(gòu)方法需要以一種特定的格式記錄下來。這些重構(gòu)手法到底有多成熟本書中提到的重構(gòu)手法第章。做法創(chuàng)造新函數(shù),以用途命名提煉代碼到函數(shù)中檢查變量名是否符合規(guī)范在源函數(shù)中,將被提煉代碼替換為函數(shù)引用測試范例重構(gòu)前重構(gòu)后 什么是重構(gòu)列表 重構(gòu)方法需要以一種特定的格式記錄下來。按照格式記錄下來的重構(gòu)方法的集合叫重構(gòu)列表 重構(gòu)的記錄格式 每個重構(gòu)手法可分為5個部分: 名稱 構(gòu)建重構(gòu)詞匯...
摘要:改進代碼設(shè)計的一個重要原則就是消除重復代碼使軟件更容易被理解優(yōu)秀的代碼能夠讓接收你代碼的付出更少的學習成本。重構(gòu)更容易找到重構(gòu)能加深對代碼的理解。可以重構(gòu)的情況添加功能時可以重構(gòu)。說明你沒有發(fā)現(xiàn)代碼的錯誤。需要重構(gòu)復審代碼時可以重構(gòu)。 為何重構(gòu) 重構(gòu)不是銀彈,但是幫助你達到以下幾個目的 改進軟件設(shè)計 不良的程序需要更多的代碼。而代碼越多,正確的修改就越困難。改進代碼設(shè)計的一個重要原則就...
摘要:通常,這種模式是通過定義一個代表處理對象的抽象類來實現(xiàn)的,在抽象類中會定義一個字段來記錄后續(xù)對象。工廠模式使用表達式第章中,我們已經(jīng)知道可以像引用方法一樣引用構(gòu)造函數(shù)。 一、為改善可讀性和靈活性重構(gòu)代碼 1.改善代碼的可讀性 Java 8的新特性也可以幫助提升代碼的可讀性: 使用Java 8,你可以減少冗長的代碼,讓代碼更易于理解 通過方法引用和Stream API,你的代碼會變得更...
閱讀 1452·2021-09-22 16:04
閱讀 2808·2019-08-30 15:44
閱讀 896·2019-08-30 15:43
閱讀 774·2019-08-29 15:24
閱讀 1855·2019-08-29 14:07
閱讀 1143·2019-08-29 12:30
閱讀 1738·2019-08-29 11:15
閱讀 2750·2019-08-28 18:08