四刷 0500 冊 (2007/01)  
三刷 0500 冊 (2005/11)  
二刷 1000 冊 (2003/11)  
一刷 2000 冊 (2003/08)  

《重構》
— 改善既有程式的設計

(繁體版)

Refactoring - Improving the Design of Existing Code

侯捷 / 熊節 譯

refactoring-b5.jpg (82283 bytes)

封面封底全圖

英文版勘誤 :http://www.refactoring.com/errata.html

繁體中文版勘誤

侯捷推薦相關書籍:《Refactoring to Patterns》,《Design Patterns》


□中譯書名:重構 — 改善既有程式的設計
□適合對象:高階程式員
□內容特色:將如何重構既有系統的步驟系統化地加以整理和描述。使用Java語言。
□製作特色:含 index,網片輸出,精裝白書籤絲條。

開放檔案如下:(請注意,預覽品與正式出版品之間可能會有微小差異)

檔名 內容 大小 bytes
refactoring-ch1-ch6.pdf

不需密碼即可開啟。
檔案含書籤(目錄連結)

請注意:本書之所有 refactoring name 和
bad smells 皆保留原文不譯。
譯序 by 侯捷
譯序 by 熊節
目錄
原序
前言
1~6章
索引
2,151,797
efile-refactoring-chap01.zip

第一章
程式源碼(by 侯捷)
9,855

如欲下載,請將滑鼠移至上述 hyperlink,按右鍵,再選【另存目標...】即可。

 

譯序by侯捷

過鐵路道班工人嗎?提著手持式砸道機,機身帶著鈍鈍扁扁的鑽頭,在鐵道上、枕木間賣力地「砍劈鑽鑿」。他們在做什麼?他們在使路基上的碎石塊(道碴)因持續劇烈的震動而翻轉方向、滑動位置,甚至震碎為更小石塊填滿縫隙,以求道碴更緊密契合,提供鐵道更安全更強固的體質。

當「重構」(refactoring)映入眼簾,我的大腦牽動「道班工人+電動砸道機+枕木道碴」這樣一幅聯想畫面。「重構」一詞非常清楚地說明了它自身的意義和價值:在不破壞可察功能的前提下,藉由搬移、提煉、打散、凝聚…,改善事物的體質。很多人認同這樣一個信念:「非常的建設需要非常的破壞」,但是現役的應用軟體、構築過半的專案、運轉中的系統,容不得推倒重來。這時候,在不破壞可察功能的前提下改善體質、強化當前的可讀性、為將來的擴充性和維護性做準備、乃至於在過程中找出潛伏的「臭蟲」,就成了大受歡迎的穩步前進的良方。

做為一個程式員,任誰都有看不順眼手上程式碼的經驗 程式碼來自你鄰桌那個菜鳥,或三個月前的自己。面臨此境,有人選擇得過且過;然而根據我對「程式員」人格特質的了解,更多人盼望插手整頓。挽起袖子劍及履及,其勇可嘉其慮未縝。過去或許不得不暴虎憑河,忍受風險。現在,有了嚴謹的重構準則和嚴密的重構手法,「穩定中求發展」終於有了保障。

是的,把重構的概念和想法逐一落實在嚴謹的準則和嚴密的手法之中,正是這本《Refactoring》的最大貢獻。重構?! 呵呵,上進的程式員每天的進行式,從來不新鮮,但要強力保證「維持程式原有的可察功能,不帶進新臭蟲」,重構就不能是一項靠著天份揮灑的藝術,必須是一項工程。

我對本書的看法

初初閱讀本書,屢屢感覺書中所列的許多重構目標過於平淡,重構步驟過於瑣屑。這些我們平常也都做、習慣大氣揮灑的動作,何必以近乎枯燥的過程小步前進?然後,漸漸我才體會,正是這樣的小步與緩步前進,不過激,不躁進,再加上完整的測試配套(是的,測試之於重構極其重要),才是「不帶來破壞,不引入臭蟲」的最佳保障。我個人其實不敢置信有誰能夠乖乖地按步遵循實現本書所列諸多被我(從人的角度)認為平淡而瑣屑的重構步驟。我個人認為,本書的最大價值,除了呼籲對軟體品質的追求態度,以及對重構「工程性」的認識,最終最重要的價值還在於:建立起吾人對於「目前和未來之自動化重構工具」的基本理論和實作技術上的認識與信賴。人類眼中平淡瑣屑的步驟,正是自動化重構工具的基礎。機器缺乏人類的「大局觀」智慧,機器需要的正是切割為一個一個極小步驟的指令。一板一眼,一次一點點,這正是機器所需要的,也正是機器的專長。

本書第14章提到,Smalltalk開發環境已含自動化重構工具。我並非Smalltalk guy,我沒有用過這些工具。基於技術的飛快滾動(或我個人的孤陋寡聞),或許如今你已經可以在Java, C++ 等物件導向編程環境中找到這一類自動化重構工具。

軟體技術圈內,重構(refactoring)常常被拿來與設計範式(design patterns)並論。書籍市場上,《Refactoring》也與《Design Patterns》齊名。GoF曾經說『設計範式為重構提供了目標』,但本書作者Martin亦言『本書並沒有提供助你完成所有知名範式的重構手法,甚至連 GoF 的23個知名範式都沒有能夠全部涵蓋。』我們可以從這些話中理解技術的方向,以及書籍所反映的侷限。我並不完全贊同Martin所言『哪怕你手上有一個糟糕的設計或甚至一團混亂,你也可以藉由重構將它加工成設計良好的程式碼。』但我十分同意Martin說『你會發現所謂設計不再是一切動作的前提,而是在整個開發過程中逐漸浮現出來。』我比較擔心,閱歷不足的程式員在讀過本書後可能發酵出「先動手再說,死活可重構」的心態,輕忽了事前優秀設計的重要性。任何技術上的說法都必須有基本假設;雖然重構(或更向上說XPeXtreme Programming)的精神的確是「不妨先動手」,但若草率行事,代價還是很高的。重型開發和輕型開發各有所長,各有應用,世間並無萬應靈藥,任何東西都不能極端。過猶不及,皆不可取!

當然,「重構工程」與「自動化重構工具」可為我們帶來相當大幅度的軟體品質提昇,這一點我毫無異議,並且非常期待J

關於本書製作

本書在翻譯與製作上保留了所有壞味道(bad smell)、重構(refactoring)、設計範式(design patterns)的英文名稱,並表現以特殊字型;只在封面內頁、目錄、小節標題中相應地給出一個根據字面或技術意義而做的中文譯名。各種「壞味道」名稱儘量就其意義選用負面字眼,如泥團、夸夸、過長、過大、過多、情結、偏執、驚悚、狎暱、純稚、冗員…。這些其實都是助憶之用,與茶餘飯後的談資(以及讀者批評的根據J )。

原書各小節並無序號。為便利參考、檢索或討論時的方便,我為譯本加上了序號。

本書保留相當份量的英文術語,時而英中並陳(英文為主,中文為輔)。這麼做的考量是,本書讀者不可能不知道class, final, reference, public, package…這些簡短的、與Java編程息息相關的用詞。另一方面,我確實認為,中文書內保留經過挑選的某些英文術語,有利於整體閱讀效果。

兩個需要特別說明的用詞是Java編程界慣用的 "field" "method"。它們相當於C++ "data member" "member function"。由於出現次數實在頻繁,為降低中英夾雜程度,我把它們分別譯為「欄位」和「函式」 如果將 "method" 譯為「方法」,恐怕術語突出性不高。此外,本書將「創造建立新物件」的 "create" 動作譯為「創建」。「static欄位與instance欄位」、「reference物件與value物件」等等則保留部分英文,並選用如上的特殊字型。凡此總總,相信一進入書中您很快可以感受本書術語風格。

本書還有諸多地方採中英並陳(中文為主,英文為輔)方式,意在告訴讀者,我們(譯者)深知自己的不足與侷限,惟恐造成您對中譯名詞的誤解或不習慣,所以附上原文。

中文版(本書)已將英文版截至2003/06/18為止之勘誤,修正於紙本。

一點點感想

Martin Fowler表現於原書的寫作風格是:簡潔,愛用代名詞和略稱。這使得讀者往往需要在字面上揣度推敲。我期盼(並相信)經過技術意義的反芻、中英術語的並陳、中文表述的努力,中文版(本書)在閱讀時間和理解時間和記憶深度上,較之英文版,能夠為以華文為母語的讀者提高10倍以上的成效。

本書由我和熊節先生合譯。熊節負責第一個pass,我負責後繼工作。中文版(本書)為讀者帶來的閱讀和理解上的效益,熊節居於首功 雖說做的是第一個pass,我從初稿品質便可看出他多次反覆推敲和文字琢磨的刻痕。至於整體風格、中英術語的選定、版面的呈現、乃至於全盤技術內涵的表現,如果有任何差錯,責任都是我的J

做為一個資訊技術教育者,以及一個資訊技術傳播者,我在超過10年的寫譯歷程中,觀察了不同級別的技術書品在讀書市場上的興衰起伏。這些適可反映大環境下技術從業人員及學子們的某些面向和取向。我很高興看到我們的中文技術書籍(著譯皆含)從早期盈盈滿滿的初階語言用書,逐漸進化到中高階語言用書、作業系統、技術內核、程式庫/框架、再至設計/分析、軟體工程。我很高興看到這樣的變化。我很高興看到《Design Patterns》、《Refactoring》、《Agile》、《UML》、《XP》之類的書在中文書籍市場中現身,並期盼它們有豐富的讀者。

中文版(本書)支援網站有一個「術語 英中繁簡」對照表。如果您有需要,歡迎訪問,網址如下,並歡迎給我任何意見。謝謝。

侯捷 2003/06/18 于臺灣.新竹

jjhou@jjhou.com(電子郵箱)
http://www.jjhou.com(繁體)(術語對照表http://www.jjhou.com/terms.htm
http://jjhou.csdn.net(簡體)(術語對照表http:// jjhou.csdn.net/terms.htm

 

英文版目錄

Table Of Contents

1. Refactoring, a First Example.
The Starting Point.
The First Step in Refactoring.
Decomposing and Redistributing the Statement Method.
Replacing the Conditional Logic on Price Code with Polymorphism.
Final Thoughts.


2. Principles in Refactoring.
Defining Refactoring.
Why Should You Refactor?
When Should You Refactor?
What Do I Tell My Manager?
Problems with Refactoring.
Refactoring and Design.
Refactoring and Performance.
Where Did Refactoring Come From?

3. Bad Smells in Code.
Duplicated Code.
Long Method.
Large Class.
Long Parameter List.
Divergent Change.
Shotgun Surgery.
Feature Envy.
Data Clumps.
Primitive Obsession.
Switch Statements.
Parallel Inheritance Hierarchies.
Lazy Class.
Speculative Generality.
Temporary Field.
Message Chains.
Middle Man.
Inappropriate Intimacy.
Alternative Classes with Different Interfaces.
Incomplete Library Class.
Data Class.
Refused Bequest.
Comments.

4. Building Tests.
The Value of Self-testing Code.
The JUnit Testing Framework.
Adding More Tests.

5. Toward a Catalog of Refactorings.
Format of the Refactorings.
Finding References.
How Mature Are These Refactorings?

6. Composing Methods.
Extract Method.
Inline Method.
Inline Temp.
Replace Temp with Query.
Introduce Explaining Variable.
Split Temporary Variable.
Remove Assignments to Parameters.
Replace Method with Method Object.
Substitute Algorithm.

7. Moving Features Between Objects.
Move Method.
Move Field.
Extract Class.
Inline Class.
Hide Delegate.
Remove Middle Man.
Introduce Foreign Method.
Introduce Local Extension.

8. Organizing Data.
Self Encapsulate Field.
Replace Data Value with Object.
Change Value to Reference.
Change Reference to Value.
Replace Array with Object.
Duplicate Observed Data.
Change Unidirectional Association to Bidirectional.
Change Bidirectional Association to Unidirectional.
Replace Magic Number with Symbolic Constant.
Encapsulate Field.
Encapsulate Collection.
Replace Record with Data Class.
Replace Type Code with Class.
Replace Type Code with Subclasses.
Replace Type Code with State/Strategy.
Replace Subclass with Fields.

9. Simplifying Conditional Expressions.
Decompose Conditional.
Consolidate Conditional Expression.
Consolidate Duplicate Conditional Fragments.
Remove Control Flag.
Replace Nested Conditional with Guard Clauses.
Replace Conditional with Polymorphism.
Introduce Null Object.
Introduce Assertion.

10. Making Method Calls Simpler.
Rename Method.
Add Parameter.
Remove Parameter.
Separate Query from Modifier.
Parameterize Method.
Replace Parameter with Explicit Methods.
Preserve Whole Object.
Replace Parameter with Method.
Introduce Parameter Object.
Remove Setting Method.
Hide Method.
Replace Constructor with Factory Method.
Encapsulate Downcast.
Replace Error Code with Exception.
Replace Exception with Test.

11. Dealing with Generalization.
Pull Up Field.
Pull Up Method.
Pull Up Constructor Body.
Push Down Method.
Push Down Field.
Extract Subclass.
Extract Superclass.
Extract Interface.
Collapse Hierarchy.
Form Template Method.
Replace Inheritance with Delegation.
Replace Delegation with Inheritance.

12. Big Refactorings.
Tease Apart Inheritance.
Convert Procedural Design to Objects.
Separate Domain from Presentation.
Extract Hierarchy.

13. Refactoring, Reuse, and Reality.
A Reality Check.
Why Are Developers Reluctant to Refactor Their Programs?
A Reality Check (Revisited).
Resources and References for Refactoring.
Implications Regarding Software Reuse and Technology Transfer.
A Final Note.
References.

14. Refactoring Tools.
Refactoring with a Tool.
Technical Criteria for a Refactoring Tool.
Practical Criteria for a Refactoring Tool.
Wrap Up.

15. Putting It All Together.

References.
List of Soundbites.
List of Refactorings.
Index