內容簡介
本書清晰揭示了重構的過程,解釋了重構的原理和最佳實踐方式,並給出了何時以及何地應該開始挖掘代碼以求改善。書中給出了70多個可行的重構,每個重構都介紹了一種經過驗證的代碼變換手法的動機和技術。本書提出的重構準則將幫助你一次一小步地修改你的代碼,從而減少了開發過程中的風險。
本書適合軟體開發人員、項目管理人員等閱讀,也可作為高等院校計算機及相關專業師生的參考讀物。
作品鑑賞
“這《重構:改善既有代碼的設計》之於重構就相當於韻譜之於作詩。一個翻著韻書作詩的詩人一定是蹩腳的,但好的詩人卻要對那109個韻部瞭然於胸;同樣,一個好的程式設計師要求能夠主動自然地重構代碼,雖不應翻著重構手冊幹活,但需對《重構:改善既有代碼的設計》中提到的70多個重構方法成竹在胸。然而,在達到這一境界之前,需要不斷的實踐和經驗積累,並且要先讀讀Fowler的這《重構:改善既有代碼的設計》。”
“一口氣讀完了這《重構:改善既有代碼的設計》,感覺書中作者對代碼的整理不像是一種技術,更像是一種藝術。”
“太經典了,看這《重構:改善既有代碼的設計》真有醍醐灌頂的感覺。”
“處於金字塔頂部的書不多,而這一《重構:改善既有代碼的設計》恰恰就是,很幸運我看到了它。”
“這《重構:改善既有代碼的設計》本質上是向我們推薦了一種優秀的編程習慣和編程態度。在領會《重構:改善既有代碼的設計》思想的同時,我們也應該培養一種精益求精的工作態度,探索一條更適合自己的重構道路。”
“今年已經看了兩遍,每次都有很大的收穫。特別喜歡其中對其他章節的索引,當你把它作為一個手邊隨時翻閱的參考書看時,它不知不覺引導你讀了很多內容,問題也在不知不覺中有了求解思路,最終得以解決。”
“不要寫完代碼就束之高閣,適當地最佳化代碼結構,能夠為以後的開發帶來許多方便,這《重構:改善既有代碼的設計》就向你介紹了這方面的技巧,說得非常詳細。”
“程式幾乎離不開重構,但如何更加迅速有效地重構卻一直沒有系統性的指導。《重構:改善既有代碼的設計》就是這樣的經典巨著,有了它,重構不再煩瑣!”
軟體開發的不朽經典,生動闡述重構原理和具體做法,普通程式設計師進階到編程高手必須修煉的秘笈。
重構,一言以蔽之,就是在不改變外部行為的前提下,有條不紊地改善代碼。多年前,正是《重構:改善既有代碼的設計》原版的出版,使重構終於從編程高手們的小圈子走出,成為眾多普通程式設計師日常開發工作中不可或缺的一部分。《重構:改善既有代碼的設計》也因此成為與《設計模式》齊名的經典著作,被譯為中、德、俄、日等眾多語言,在世界範圍內暢銷不衰。
《重構:改善既有代碼的設計》凝聚了軟體開發社區專家多年摸索而獲得的寶貴經驗,擁有不因時光流逝而磨滅的價值。今天,無論是重構本身,業界對重構的理解,還是開發工具對重構的支持力度,都與《重構:改善既有代碼的設計》最初出版時不可同日而語,但書中所蘊涵的意味和精華,依然值得反覆咀嚼,而且往往能夠常讀常新。
作者簡介
作者:(美國)福勒(Martin Fowler) 譯者:熊節
Martin Fowler,世界軟體開發大師,在面向對象分析設計、UML、模式、XP和重構等領域都有卓越貢獻,現為著名軟體開發諮詢公司ThoughtWorks的首席科學家。他的多部著作《分析模式》、《UML精粹》和《企業套用架構模式》等都已經成為膾炙人口的經典。
Martin Fowler是一位獨立諮詢顧問,他運用對象技術解決企業問題已經超過十年。他的顧問領域包括健康管理、金融貿易,以及法人財務。他的客戶包括Chrysler,Citibank,UK National Health Service,AndersenConsulting,NetscapeCommunications。此外Fowler也是objects、UML、patterns技術的一位合格講師,他是《AnalysisPatterns》和《UML Distilled》的作者。
熊節,ThoughtWorks中國公司的高級諮詢師、架構師和項目經理,在大型企業套用及網際網路套用的架構和管理方面擁有豐富經驗。作為敏捷方法學顧問和重構專家,他擁有在各種技術平台、程式語言、軟體形態的項目中實施重構的豐富經驗,並曾主持極具挑戰性的超大規模電信軟體系列重構工作。
作品目錄
第1章 重構,第一個案例
1.1 起點1
1.2 重構的第一步7
1.3 分解並重組statement()8
1.4 運用多態取代與價格相關的條件邏輯34
1.5 結語52
第2章 重構原則
2.1 何謂重構53
2.2 為何重構55
2.3 何時重構57
2.4 怎么對經理說60
2.5 重構的難題62
2.6 重構與設計66
2.7 重構與性能69
2.8 重構起源何處71
第3章 代碼的壞味道
3.1 DuplicatedCode(重複代碼)76
3.2 LongMethod(過長函式)76
3.3 LargeClass(過大的類)78
3.4 LongParameterList(過長參數列)78
3.5 DivergentChange(發散式變化)79
3.6 ShotgunSurgery(霰彈式修改)80
3.7 FeatureEnvy(依戀情結)80
3.8 DataClumps(數據泥團)81
3.9 PrimitiveObsession(基本類型偏執)81
3.10 SwitchStatements(switch驚悚現身)82
3.11 ParallelInheritanceHierarchies(平行繼承體系)83
3.12 LazyClass(冗贅類)83
3.13 SpeculativeGenerality(誇誇其談未來性)83
3.14 TemporaryField(令人迷惑的暫時欄位)84
3.15 MessageChains(過度耦合的訊息鏈)84
3.16 MiddleMan(中間人)85
3.17 InappropriateIntimacy(狎昵關係)85
3.18 AlternativeClasseswithDifferentInterfaces(異曲同工的類)85
3.19 IncompleteLibraryClass(不完美的庫類)86
3.20 DataClass(純稚的數據類)86
3.21 RefusedBequest(被拒絕的遺贈)87
3.22 Comments(過多的注釋)87
第4章 構築測試體系
4.1 自測試代碼的價值89
4.2 JUnit測試框架91
4.3 添加更多測試97
第5章 重構列表
5.1 重構的記錄格式103
5.2 尋找引用點105
5.3 這些重構手法有多成熟106
第6章 重新組織函式
6.1 ExtractMethod(提煉函式)110
6.2 InlineMethod(內聯函式)117
6.3 InlineTemp(內聯臨時變數)119
6.4 ReplaceTempwithQuery(以查詢取代臨時變數)120
6.5 IntroduceExplainingVariable(引入解釋性變數)124
6.6 SplitTemporaryVariable(分解臨時變數)128
6.7 RemoveAssignmentstoParameters(移除對參數的賦值)131
6.8 ReplaceMethodwithMethodObject(以函式對象取代函式)135
6.9 SubstituteAlgorithm(替換算法)139
第7章 在對象之間搬移特性
7.1 MoveMethod(搬移函式)142
7.2 MoveField(搬移欄位)146
7.3 ExtractClass(提煉類)149
7.4 InlineClass(將類內聯化)154
7.5 HideDelegate(隱藏“委託關係”)157
7.6 RemoveMiddleMan(移除中間人)160
7.7 IntroduceForeignMethod(引入外加函式)162
7.8 IntroduceLocalExtension(引入本地擴展)164
第8章 重新組織數據
8.1 SelfEncapsulateField(自封裝欄位)171
8.2 ReplaceDataValuewithObject(以對象取代數據值)175
8.3 ChangeValuetoReference(將值對象改為引用對象)179
8.4 ChangeReferencetoValue(將引用對象改為值對象)183
8.5 ReplaceArraywithObject(以對象取代數組)186
8.6 DuplicateObservedData(複製“被監視數據”)189
8.7 ChangeUnidirectionalAssociationtoBidirectional(將單向關聯改為雙向關聯)197
8.8 ChangeBidirectionalAssociationtoUnidirectional(將雙向關聯改為單向關聯)200
8.9 ReplaceMagicNumberwithSymbolicConstant(以字面常量取代魔法數)204
8.10 EncapsulateField(封裝欄位)206
8.11 EncapsulateCollection(封裝集合)208
8.12 ReplaceRecordwithDataClass(以數據類取代記錄)217
8.13 ReplaceTypeCodewithClass(以類取代類型碼)218
8.14 ReplaceTypeCodewithSubclasses(以子類取代類型碼)223
8.15 ReplaceTypeCodewithState/Strategy(以State/Strategy取代類型碼)227
8.16 ReplaceSubclasswithFields(以欄位取代子類)232
第9章 簡化條件表達式
9.1 DecomposeConditional(分解條件表達式)238
9.2 ConsolidateConditionalExpression(合併條件表達式)240
9.3 ConsolidateDuplicateConditionalFragments(合併重複的條件片段)243
9.4 RemoveControlFlag(移除控制標記)245
9.5 ReplaceNestedConditionalwithGuardClauses(以衛語句取代嵌套條件表達式)250
9.6 ReplaceConditionalwithPolymorphism(以多態取代條件表達式)255
9.7 IntroduceNullObject(引入Null對象)260
9.8 IntroduceAssertion(引入斷言)267
第10章 簡化函式調用
10.1 RenameMethod(函式改名)273
10.2 AddParameter(添加參數)275
10.3 RemoveParameter(移除參數)277
10.4 SeparateQueryfromModifier(將查詢函式和修改函式分離)279
10.5 ParameterizeMethod(令函式攜帶參數)283
10.6 ReplaceParameterwithExplicitMethods(以明確函式取代參數)285
10.7 PreserveWholeObject(保持對象完整)288
10.8 ReplaceParameterwithMethods(以函式取代參數)292
10.9 IntroduceParameterObject(引入參數對象)295
10.10 RemoveSettingMethod(移除設值函式)300
10.11 HideMethod(隱藏函式)303
10.12 ReplaceConstructorwithFactoryMethod(以工廠函式取代構造函式)304
10.13 EncapsulateDowncast(封裝向下轉型)308
10.14 ReplaceErrorCodewithException(以異常取代錯誤碼)310
10.15 ReplaceExceptionwithTest(以測試取代異常)315
第11章 處理概括關係
11.1 PullUpField(欄位上移)320
11.2 PullUpMethod(函式上移)322
11.3 PullUpConstructorBody(構造函式本體上移)325
11.4 PushDownMethod(函式下移)328
11.5 PushDownField(欄位下移)329
11.6 ExtractSubclass(提煉子類)330
……
2第13章 重構,復用與現實
作品序言
第一次聽到“重構”這個詞,是在2001年10月。在當時,它的思想足以令我感到震撼。軟體自有其美感所在。軟體工程希望建立完美的需求與設計,按照既有的規範編寫標準劃一的代碼,這是結構的美;快速疊代和RAD顛覆“全知全能”的神話,用近乎刀劈斧砍(crack)的方式解決問題,在混沌的循環往復中實現需求,這是解構的美;而Kent Beck與Martin Fowler兩人站在一起,以XP那敏捷而又嚴謹的方法論演繹了重構的美——我不知道是誰最初把refactoring一詞翻譯為“重構”,或許無心插柳,卻成了點睛之筆。
我一直是設計模式的愛好者。曾經在我的思想中,軟體開發應該有一個“理想國”——當然,在這個理想國維持著完美秩序的,不是哲學家,而是模式。設計模式給我們的,不僅僅是一些具體問題的解決方案,更有追求完美“理型”的渴望。但是,Joshua Kerievsky在那篇著名的《模式與XP》(收錄於《極限編程研究》一書)中明白地指出:在設計前期使用模式常常導致過度工程(over-engineering)。這是一個殘酷的現實,單憑對完美的追求無法寫出實用的代碼,而“實用”是軟體壓倒一切的要素。從一篇《停止過度工程》開始,Kerievsky撰寫了“Refactoring to Patterns”系列文章。這位猶太人用他民族性的睿智頭腦,敏銳地發現了軟體的後結構主義道路。而讓設計模式在飛速變化的網路時代重新閃現光輝的,又是重構的力量。
在一篇流傳甚廣的帖子裡,有人把《重構》與《設計模式》並列為“Java行業的聖經”。在我看來這種並列其實並不準確。實際上,儘管我如此喜愛這本《重構》,但自從完成翻譯之後,就再也沒有讀過它。不,不是因為我已經對它爛熟於心,而是因為重構已經變成了我的另一種生活方式,變成了我每天的“麵包與黃油”,變成了我們整個團隊的空氣與水,以至於無需再到書中尋找任何“神諭”。而《設計模式》,我倒是放在手邊時常翻閱,因為總是記得不那么真切。