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