Time of Update: 2018-12-07
某個函數需要從調用端得到更多資訊。為此函數添加一個對象參數,讓該對象帶進函數所需資訊。動機:Add Parameter (添加參數)是一個很常用的重構手法。使用這項重構的動機很簡單:你必須修改一個函數,而修改後的函數需要一些過去沒有的資訊,因此你需要給該函數添加一個參數。
Time of Update: 2018-12-07
你有一些子類,其中相應的某些函數以相同的順序執行類似的操作,但各個操作的細節不同。將這些操作分別放進獨立的函數中,並保持它們都有相同的簽名,於是原函數也就變得相同了,然後將原函數上移至超類。動機:繼承是避免重複行為的一個強大工具。無論何時,只要你看見2個子類之中有類似的函數,就可以把它們提升到超類。但是如果這些函數並不完全相同該這麼辦?仍有必要盡量避免重複,但又必須保持這些函數之間的實質差異。
Time of Update: 2018-12-07
某個函數返回一個特定的代碼,用以表示某種錯誤情況。改用異常。動機:程式中發現錯誤的地方,並不一定知道如何處理錯誤。當一段子程式發現錯誤時,它需要讓它的調用者知道這個錯誤,而調用者也可能將這個錯誤繼續沿著調用鏈傳遞上去。許多程式都使用特殊輸出來表示錯誤。 可以使用更好的錯誤處理方式:異常。它清楚地將“普通程式”和“錯誤處理”分開了,這使得程式更容易理解:代碼的可理解性應該是我們追求的目標。
Time of Update: 2018-12-07
你有一個複雜的條件陳述式。從if、then、else三個段落中分別提煉出獨立函數。動機:程式之中,複雜的條件邏輯是最常導致複雜度上升的地點之一。你必須編寫代碼來檢查不同的條件分支、根據不同的分支做不同的事,然後,你很快就會得到一個相當長的函數。大型函數自身就會使代碼的可讀性下降,而條件邏輯則會使代碼更難閱讀。在帶有複雜條件邏輯的函數中,代碼(包括檢查條件分支的代碼和真正實現功能的代碼)會告訴你發生的事,當常常讓你弄不清為什麼會發生這樣的事,這就說明代碼的可讀性的確大大降低了。
Time of Update: 2018-12-07
函數本體不再需要某個函數。將該參數去除。動機:程式員可能檢查添加參數,卻往往不願意去掉它們。他們打的如意算盤是:無論如何,多餘的參數不會引起任何問題,而且以後還可能用上它。 參數代表著函數所需的資訊,不同的參數值有不同的意義。函數調用者必須為每一個參數操心該傳什麼東西進去。如果你不去掉多餘參數,就是讓你的每一位使用者多費一份心。是很不划算的,更何況“去除參數”是非常簡單的一項重構。
Time of Update: 2018-12-07
函數對某個類的興趣高過對自己所處的類,通常的焦點就是資料,某個函數為了計算某個值,從另一個對象那兒調用幾乎半打的存取子。這時一個運用 Move Method (搬移函數)把它移到自己該去的地方。有時候函數中只有一部分受這種依戀之苦,這時候使用Extract Method (提煉函數)把這部分提煉到獨立函數中,再使用Move Method (搬移函數)帶它去它的夢中家園。
Time of Update: 2018-12-07
平行繼承體系其實是散彈式修改(Shotgun Surgery)的特殊情況。在這種情況下,每當你為某個類增加1個子類,必須也為另一個類相應增加1個子類。如果你發現某個繼承體系的類名首碼和另一個繼承體系的類名首碼完全相同,便是聞到了這種壞味道。 消除這種重複性的一般策略是:讓一個繼承體系的執行個體引用另一個繼承體系的執行個體。如果再接再厲運用 Move Method (搬移函數)和Move Field (搬移欄位),,就可以將引用端的繼承體系取消。
Time of Update: 2018-12-07
你的程式中,有個函數與其所駐類之外的另一個類進行更多的交流:調用後者,或被後者調用。在該函數最常用引用的類中建立一個有著類似行為的新函數。將舊函數編程一個單純的委託函數,或是將舊函數完全移除。 動機:“搬移函數”是重構理論的支柱。如果一個類有太多行為,或如果一個類與另一個類有太多合作而形成高度耦合,就需要搬移函數。通過這種手段,可以使系統中的類更簡單,這些類最終也將更乾淨利落的實現系統交付的工作。
Time of Update: 2018-12-07
某個函數返回的對象,需要由函數調用者執行向下轉型(downcast)。將向下轉型動作移到函數中。動機:向下轉型也許是無法避免的,但你仍然應該儘可能少做。如果你的某個函數返回一個值,並且你知道所返回的物件類型比函數簽名所昭告的更特化,你便是在函數使用者身上強加了非必要的工作。這種情況下你不應該要求使用者承擔向下轉型的責任,應該盡量為他們提供準確的類型。
Time of Update: 2018-12-07
對象技術的新手通常不願意在小任務上運用小對象—像是結合數值和幣種的money類,由一個起始值和結束值組成的range類等。你可以使用 Replace Data Value with Object (以對象取代資料值)將原本單獨存在的資料值替換為對象。如果想要替換的資料值是類型碼,而它並不影響行為,則可以運用 Replace Type Code with Class (以類取代類型碼)將它替換掉。如果你有與類型碼相關的條件運算式,可運用 Replace Type Code with
Time of Update: 2018-12-07
客戶通過一個委託類在調用另一個對象。在服務類上建立客戶所需的所有函數,用以隱藏委託關係。動機:“封裝”即使不是對象的關鍵特徵,也是關鍵特徵之一。“封裝”意味每個對象都有應該儘可能少瞭解系統的其他部分。如此一來,一旦發生變化,需要瞭解這一變化的對象就會比較少,這會使變化較容易進行。 如果某個客戶先通過服務物件的欄位得到另一個對象,然後調用後者的函數,那麼客戶就必須知曉這一層委託關係。萬一委託關係發生變化,客戶也得相應變化。你可以在服務物件上放置一個簡單的委託函數,將委託關係隱藏起來,
Time of Update: 2018-12-07
你有一系列條件測試,都得到相同結果。將這些測試合并為一個條件運算式,並將這個條件運算式提煉為一個獨立函數。動機:有時你會發現這樣一串條件檢查:檢查條件各不相同,最終行為卻一致。如果發現這種情況,就應該使用“邏輯或”和“邏輯與”將它們合并為一個條件運算式。
Time of Update: 2018-12-07
你有一個字面數值,帶有特別含義。建立一個常量,根據其意義為它命名,並將上述的字面數值替換為這個常量。動機:在計算科學中,魔法數是曆史悠久的不良現象之一。所謂魔法數是指擁有特殊意義,卻又不能明確表現出這種意義的數字。如果你需要在不同的地點引用同一個邏輯數,魔法數會讓你煩惱不已,因為一旦這些數發生變化,你就必須在程式中找到所有魔法數,並將它們全部修改一遍。就算你不需要修改,要準確指出每個魔法數的用途,也會讓你頗費腦筋。
Time of Update: 2018-12-07
某個函數既返回對象狀態值,又修改對象狀態。建立2個不同的函數,其中一個負責查詢,另一個負責修改。動機:如果某個函數只是向你提供一個值,沒有任何看得到的副作用,那麼這是個很有價值的東西。你可以任意調用這個函數,也可能把調用動作搬到函數的其他地方。明確表現出”有副作用”與“無副作用”2種函數之間的差異,是個很好的想法。任何有傳回值的函數,都不應該有看得到的副作用。有些程式員甚至將此作為一條必須遵守的規則。
Time of Update: 2018-12-07
你想要把某個演算法替換為另一個更清晰地演算法。將函數本體替換為另一個演算法。 string FoundPerson(string[] people) { for (int i = 0; i < people.Length; i++) { if (people[i].Equals("don")) { return "don";
Time of Update: 2018-12-07
常常可以在很多地方看到相同的3、4項資料:2個類中相同的欄位、許多函數簽名中相同的參數。這些總是綁在一起出現的資料真應該擁有屬於它們自己的對象。首先找出這些資料以欄位形式出現的地方,運用Extract Class (提煉類)將它們提煉到一個獨立對象中。然後將注意力轉移到函數簽名上,運用Introduce Parameter Object (引入參數對象)或Preserve Whole Object
Time of Update: 2018-12-07
你需要為提供服務的類增加一個函數,但你無法修改這個類。在客戶類中建立一個函數,並以第一參數形式傳入一個服務類執行個體。 動機:這種事情發生了太多次了,你正在使用一個類,它真的很好,為你提供了需要的所有服務。而後,你又需要一項新服務,這個類卻無法供應。於是你開始咒罵“為什麼不能做這件事?”如果可以修改源碼,你便可以自行添加一個新函數;如果不能,你就得在用戶端編碼,補足你要的那個函數。
Time of Update: 2018-12-07
某個類沒有做太多事情。將這個類的所有特性搬移到另一個類中,然後移除原類。動機:Inline Class (將類內聯化)正好於Extract Class (提煉類)相反。如果一個類不再承擔足夠責任、不再有單獨存在的理由(這通常是因為此前的重構動作移走了這個類的責任),就挑選這個“萎縮類”的最頻繁的使用者(也是個類),以Inline Class
Time of Update: 2018-12-07
Silverlight中的資源一、使用相同組件中的資源檔1、xaml檔案和資源檔目錄同級 用image樣本 <Image x:Name="Image1" Source="Images/xxx.png" /> Images檔案夾和MainPage.xaml檔案在同級目錄中 2、xaml檔案和資源檔夾不同級 <Image x:Name="Image1" Source="../Images/xxx.png"
Time of Update: 2018-12-07
若干函數做了類似的工作,但在函數本體中卻包含了不同的值。建立一個單一函數,以參數表達那些不同的值。動機:你可能會發現這樣的2個函數:它們做著類似的工作,但因少數幾個值致使行為略為不同。這種情況下,你可以將這些各自分離的函數統一起來,並通過參數來處理那些變化,用以簡化問題。這樣的修改可以去除重複代碼,並提高靈活性,因為你可以用這個參數處理更多的變化情況。做法:1、建立一個帶有參數的函數,使它可以替換先前所有的重複性函數。 2、編譯。 3、將調用舊函數的代碼改為調用新函數。