摘要:函數重構重構有很大一部分都是在重構函數。這條也要具體情況具體使用函數對象取代函數函數對象代替函數大函數變成類你有一個大型函數,其中對局部變量的使用使你無法采用提煉函數。將這個大型函數放進一個多帶帶對象中,如此一來局部變量就成了對象內的字段。
函數重構
重構有很大一部分都是在重構函數。尤其是長函數。這是問題的根源。以下是重構方法
Extract Method 提煉函數提煉函數:(由復雜的函數提煉出獨立的函數或者說大函數分解成由小函數組成)你有一段代碼可以被組織在一起并獨立出來。將這段代碼放進一個獨立函數,并讓函數名稱解釋該函數的用途。
重構前
void printOwing() { //print banner System.out.println(“*********”); System.out.println(“Banner”); System.out.println(“*********”); //print details System.out.println ("name: " + _name); System.out.println ("amount " + getOutstanding()); }
重構后
void printOwing() { printBanner(); printDetails(getOutstanding()); } Void printBanner() { //print banner System.out.println(“*********”); System.out.println(“Banner”); System.out.println(“*********”); } void printDetails (double outstanding) { System.out.println ("name: " + _name); System.out.println ("amount " + outstanding); }Inline Method 內聯函數
內聯函數:(直接使用函數體代替函數調用 ) 一個函數調用的本體與名稱同樣清楚易懂。在函數調用點插入函數體,然后移除該函數
重構前
int getRating() { return moreThanfiveLateDeliverise() ? 2 : 1; } bool moreThanfiveLateDeliverise() { return _numberOfLateLiveries > 5; }
重構后
int getRating(){ return _numberOfLateLiveries > 5 ? 2 : 1; }Inline Temp 內聯臨時變量
內聯臨時變量:(表達式代替臨時變量)你有一個臨時變量,只被一個簡單表達式賦值一次,而它妨礙了其他重構手法。將所有對該變量的引用動作,替換為對它賦值的那個表達式自身
重構前
double basePrice = anOrder.BasePrice(); return basePrice(>1000);
重構后
return (anOrder.BasePrice() >1000);Replace Temp with Query 以查詢代替臨時變量
以查詢代替臨時變量:(獨立函數代替表達式)你的程序以一個臨時變量保存某一個表達式的運算效果。將這個表達式提煉到一個獨立函數中。將這個臨時變量的所有引用點替換為對新函數的調用。此后,新函數就可以被其他函數調用。
重構前
double basePrice = _quantity*_itemPrice; if (basePrice > 1000) { return basePrice * 0.95; else return basePrice * 0.98;
重構后
if (basePrice() > 1000) return basePrice() * 0.95; else return basePrice() * 0.98; …… double basePrice() { return _quantity * _itemPrice; }
注:這一條我始終不覺得合理。如果從性能上看。明顯重構前的性能會比第二種更好。而且更容易理解
Introduce Explaining Variable 引入解釋性變量引入解釋性變量:(復雜表達式分解為臨時解釋性變量)你有一個復雜的表達式。將該復雜表達式(或其中一部分)的結果放進一個臨時變量,以此變量名稱來解釋表達式用途。
重構前
if (Platform.ToUpperCass().indexOf("MAC") > -1 && (Browser.ToUpperCass().indexOf("Ie") > -1) && WasInitalized() ) { //do something }
重構后
const bool imMacOs = Platform.ToUpperCass().indexOf("MAC") > -1;
const bool isIeBrowser = Browser.ToUpperCass().indexOf("Ie") > -1;
const bool wasInitalized = WasInitalized();
if (imMacOs && isIeBrowser && wasInitalized)
{
//do something
}
注:這一條和上上條并沒有沖突。上上條指的是單純地取值函數,如get方法。這一條針對無法理解的方法鏈
分解臨時變量:(臨時變量不應該被賦值超過一次)你的程序有某個臨時變量被賦值超過一次,它既不是循環變量,也不被用于收集計算結果。針對每次賦值,創造一個獨立、對應的臨時變量
重構前
double temp = 2 + (_height + _width); Console.WriteLine(temp); temp = _height * _width; Console.WriteLine(temp);
重構后
const double perimeter = 2 + (_height + _width); Console.WriteLine(perimeter); const double area = _height * _width; Console.WriteLine(area);Remove Assigments to Parameters 移除對參數的賦值
移除對參數的賦值:(不要對參數賦值)代碼對一個 參數賦值。以一個臨時變量取代該參數的位置。
重構前
int discount (int inputVal, int quantity, int yearToDate){ if (inputVal > 50) inputVal -= 2; }
重構后
int discount (int inputVal, int quantity, int yearToDate) { int result = inputVal; if (inputVal > 50) result -= 2; }
注:如果傳的是對象。除非你想要操作對象。否則就留下了bug的風險。因為對象傳入方法被改變了。(這條也要具體情況具體使用)
Replace Method with Method object 函數對象取代函數函數對象代替函數:(大函數變成類)你有一個大型函數,其中對局部變量的使用使你無法采用 Extract Method (提煉函數)。將這個大型函數放進一個多帶帶對象中,如此一來局部變量就成了對象內的字段。然后你可以在同一個對象中將這個大型函數分解為多個小型函數。
重構前
class Order... double price() { double primaryBasePrice; double secondaryBasePrice; double tertiaryBasePrice; // long computation; ... }
重構后
class Price { double primaryBasePrice; double secondaryBasePrice; double tertiaryBasePrice; public void price(){ // long computation; ... 或者可以采用static methodSubstitute Algorithm 替換算法
替換算法:(函數本體替換為另一個算法)你想要把某個算法替換為另一個更清晰地算法。將函數本體替換為另一個算法。
重構前
String foundPerson(String[] people){ for (int i = 0; i < people.length; i++) { if (people[i].equals ("Don")){ return "Don"; } if (people[i].equals ("John")) { return "John"; } if (people[i].equals ("Kent")){ return "Kent"; } } return ""; }
重構后
String foundPerson(String[] people){ List candidates = Arrays.asList(new String[] {"Don", "John", "Kent"}); for (int i=0; i注:如果可以使用更簡單并清晰的方式。就果斷換方式
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/69704.html
摘要:哪吒社區技能樹打卡打卡貼函數式接口簡介領域優質創作者哪吒公眾號作者架構師奮斗者掃描主頁左側二維碼,加入群聊,一起學習一起進步歡迎點贊收藏留言前情提要無意間聽到領導們的談話,現在公司的現狀是碼農太多,但能獨立帶隊的人太少,簡而言之,不缺干 ? 哪吒社區Java技能樹打卡?【打卡貼 day2...
摘要:重構在不改變代碼的外在的行為的前提下對代碼進行修改最大限度的減少錯誤的幾率本質上,就是代碼寫好之后修改它的設計。重構可以深入理解代碼并且幫助找到。同時重構可以減少引入的機率,方便日后擴展。平行繼承目的在于消除類之間的重復代碼。 重構 (refactoring) 在不改變代碼的外在的行為的前提下 對代碼進行修改最大限度的減少錯誤的幾率 本質上, 就是代碼寫好之后 修改它的設計。 1,書中...
摘要:什么是重構列表重構方法需要以一種特定的格式記錄下來。這些重構手法到底有多成熟本書中提到的重構手法第章。做法創造新函數,以用途命名提煉代碼到函數中檢查變量名是否符合規范在源函數中,將被提煉代碼替換為函數引用測試范例重構前重構后 什么是重構列表 重構方法需要以一種特定的格式記錄下來。按照格式記錄下來的重構方法的集合叫重構列表 重構的記錄格式 每個重構手法可分為5個部分: 名稱 構建重構詞匯...
摘要:前言決定把責任放在哪對于對象設計是最重要的之一。重構可以很好的解決這個問題。方法建立一個新類,將相關的字段和函數從舊類搬移到新類。方法將這個類的所有特性搬移到另一個類中,然后移除原類。讓這個擴展品成為源類的子類或包裝類。 前言 決定把責任放在哪對于對象設計是最重要的之一。重構可以很好的解決這個問題。以下是筆者的重構方法注:客戶:調用接口客戶類:使用了接口的類服務類:提供服務的類 Mov...
摘要:并根據目錄選讀第章重構,第一個案例這是只是一個方法。絕大多數情況下,函數應該放在它所使用的數據的所屬對象內最好不要在另一個對象的屬性基礎上運用語句。 什么是重構 在不改變代碼外在行為的前提下,對代碼做出修改以改進程序內部的結構簡單地說就是在代碼寫好后改進它的設計 誰該閱讀這本書 專業程序員(能夠提高你的代碼質量) 資深設計師和架構規劃師(理解為什么需要重構,哪里需要重構) 閱讀技巧...
閱讀 3794·2021-11-17 09:33
閱讀 2011·2021-10-26 09:51
閱讀 1527·2021-09-29 09:44
閱讀 1678·2019-08-30 15:55
閱讀 1447·2019-08-30 15:52
閱讀 2325·2019-08-30 15:43
閱讀 3432·2019-08-29 17:00
閱讀 2302·2019-08-29 16:23