「重構」第二版

過去兩年,我一直在編寫我著作「重構」的第二版。以下是我對新版的詳細說明,以及我在這個專案最後幾個月的一些想法備忘。

這本書現在已經出版,你可以從informit icon(出版商的網路平台)、Amazon或你喜歡的書店購買。購買這本書可以讓你存取正規網路版本,其中包含實體書或電子書版本中沒有的額外資料。

這本書可能需要一段時間才能透過各種通路取得。特別是,它往往會比較慢才能到達其他國家,而且電子格式的國際供應可能會很複雜,因為它與各國的書籍通路協議有關。

如果你在取得副本時遇到困難,最好的辦法是聯絡 informit,因為我的出版商對書籍通路的複雜性比我了解得多。

詳細資料 

我很幸運能與 Kent Beck 合作C3 專案,該專案催生了極限程式設計。我從 Kent 那裡學到了很多(而且還在學習),但真正讓我印象深刻的一件事是他持續重製程式碼庫以保持其健全性的方法,這種方法當時還沒有「重構」這個名稱。在我其他諮詢工作中,我強調了這項技術的價值,但無法向人們指出可以學習它的書籍,所以我最後自己寫了這本書。它在 20 世紀結束前出版。

那是將近二十年前的事了,現在這項技術已經廣為人知,儘管通常沒有得到應有的執行。這本書也保存得很好,而且我想你可以拿這本舊書,仍然可以學習如何重構,就像你多年前所做的那樣。但這本書顯露出它的年代,例如使用 java.util.Vector

因此,多年來我一直考慮要修改它,但我也一直猶豫不決。畢竟,它仍然完美地教授了這項技術,而第二版通常不會改善原版。但是,另一股力量一直在拉扯著我。在我寫它的時候,將類別視為主導程式碼機制的結構已成為主流。然而,如今,我們看到其他結構扮演著更重要的角色。在我看來,類別仍然有價值,但我們的重構需要較少以它們為中心,了解它們可以在程式碼訓練成新形狀時來來去去。

在 2015 年和 2016 年初,我寫了一系列文章探討重構的各種情況,這有助於我了解我是否應該進行重寫,如果是,該如何進行。到了 2016 年年中,我已準備好開始這項工作。如果您一直想知道為什麼我不像以前那樣為 martinfowler.com 撰寫那麼多文章,那是因為從那時起,我的寫作精力就集中在書本上了。

第二版的變更

這些變更既非常細微,又包羅萬象。它們很細微,因為本書的基本結構沒有改變。我從一個開場範例、一章原則、一個「程式碼異味」調查和一個測試簡介開始。本書的大部分內容是重構目錄,在這些 68 個重構中,除了 10 個之外,其餘都還在,而且我新增了 17 個。(詳細資訊在此

儘管整體書籍結構沒有這種變化,但頁面上的文字變更卻很大。每個章節和重構都已重寫,大部分幾乎都是從頭開始。我很少有機會從舊版本剪貼文字。

重新導向較不以類別為中心的觀點是這項工作的一大部分。雖然這聽起來就像把「萃取方法」的名稱改為「萃取函式」一樣簡單,但這的確需要重新思考每個重構的所有面向。我需要重新考量動機,經常覺得需要重新建構。機制至少需要詳細檢閱,通常需要完全重寫。我並沒有詳細記錄這部分,但我的感覺是,對於每次舊重構的相對簡單匯入,就有兩次需要完全重新思考。

不過還有另一個改變,某種程度上來說並不重要,但勢必會引起很多關注。範例不再使用 Java。

當我在寫作中為範例選擇語言時,我主要會想到讀者。我會問:「哪種語言能幫助最多讀者理解書中的概念?」《重構》並非特定語言的書籍,其建議或許可以用 Java 中的範例說明,但重構適用於大多數語言。我選擇 Java,是因為我覺得如果用 Java 編寫範例,大多數人就能理解這些範例程式碼。1997 年時是如此,但 2017 年呢?

我考慮過使用多種語言,這會強調本書的語言中立意圖。但我覺得這會讓讀者更困惑,最好使用單一語言,讓他們能習慣一致的表達形式。那麼哪一種語言對讀者來說最容易理解?這種語言需要廣受歡迎,在語言受歡迎程度調查中名列前六。具備 C 語法基礎真的很有幫助,因為大多數程式設計師都能辨識基本的程式碼結構。考量到這一點,有兩種語言脫穎而出。一種是 Java,仍然廣泛使用且易於理解。但我選擇了另一種:JavaScript。

選擇 JavaScript 對我來說非常諷刺,因為許多讀者可能知道,我不是它的愛好者。它有太多令人尷尬的邊界情況和笨拙的慣用語。ECMAScript 2015 (ES6) 導入了一個相當好的類別模型,這使得許多物件導向重構更容易表達,但仍然有一些惱人的漏洞,從語言的早期就內建在結構中。但選擇它而非 Java 的主要原因是它並非完全以類別為中心。有頂層函式,而且通常會使用一級函式。這使得在類別的脈絡之外顯示重構變得容易許多。

網路優先的書籍

萬維網對我們的社會產生了巨大的影響,特別影響了我們收集資訊的方式。當我撰寫第一版時,大多數關於軟體開發的知識都是透過印刷品傳遞。現在我從網路上收集大部分的資訊。這對像我這樣的作者來說是一個挑戰,書籍是否還有其角色,它們應該是什麼樣子?

我相信像這樣的書籍仍然有其角色,但它們需要改變。一本書的價值在於大量的知識,以有凝聚力的方式組合在一起。在撰寫這本書時,我需要收集許多重構,並以一致且整合的方式組織它們。

但是,那個整合的整體是一個抽象的文學作品,儘管傳統上由紙本書表示,但未來不必如此。大多數的書籍產業仍將紙本書視為主要表示,儘管我們熱情地採用電子書,但這些只是基於紙本書概念的原始作品的電子表示。

有了這本書,我正在探索不同的方法。我認為這本書的標準形式是網站。紙本書是網站上材料的選集,以適合印刷的方式排列。它不會嘗試包含標準書中的所有重構,特別是因為我未來很可能會在標準網路書中新增更多重構。

我們的目的是,當您購買重構第 2 版的副本時,您可以在書店以實體形式購買,或在線上以任何形式購買。您用錢買到的最重要的東西是永久存取網站。您可以閱讀實體書,並在需要時存取網站。

這引發了一個問題,即電子書(例如 epub 和 kindle 書籍)應該扮演什麼角色。有一個強烈的論點認為它們應該包含網站上的所有資訊,畢竟實體大小不是一個因素,而且如果我新增新材料,電子書可以輕鬆更新。然而,書籍產業並不同意這種看法,他們希望電子書具有與實體書相同的內容,因此重構的電子書版本將遵循該原則,至少目前是如此。

較早備忘錄 

保持相同的範圍(2018 年 3 月 28 日) 

我想強調這個版本的一件事是,它涵蓋的範圍不比現有書籍多。它在某種程度上偏離了純粹基於類別的結構,但我的目標是不過度改變這本書的範圍。儘管有許多有吸引力的領域可以探索,但我的時間和精力有限。因此,我遵循了一條規則,不讓第二版涉足新的主題領域。即使只是嘗試做不比第一版中更多的事情,這仍然是兩年的紮實工作。我不想增加花在這上面的時間,畢竟第一版非常成功,所以我的目標是保持它的實用性,而不是嘗試創造新的東西。

我的總體計畫是採用第一版的每個重構,並詢問在這個略有變化的背景下,需要對它做些什麼才能保持相關性。在少數(令人高興的)情況下,我可以採用幾乎原樣的重構,對範例進行簡單的 JavaScript 改寫,然後完成。然而,通常需要對機制和範例進行重大的重新思考。有時這意味著原始重構被類似的事物取代。

很有可能在未來,我將探索一些新主題,並在網站上新增重構語料庫。當然,我在第一版之前就這麼想過,但大多數都沒有,所以請適當地理解這個想法。但在 2015 年和 2016 年初,我確實探討了一些關於使用重構來幫助探索各種架構問題的文章。我很喜歡寫它們,而且它們表示我未來可以輕鬆使用更多的一種載具。

審閱意見處理(2018 年 4 月 3 日) 

過去幾天(是的,包括週末)我都在處理這本書的審閱意見。二月初,我在 Pearson 的編輯將這本書的現況寄給不同的人進行技術審閱。這是寫書過程中至關重要的一部分,任何作者都會犯錯,而我也犯了不少。審閱者協助找出這些錯誤,並強調說明不清的地方。

這不是這本書資料的第一次審閱。我開始寫書時,召集了一群人進行持續審閱。每次完成一章或進行幾次重構時,我都會寄給他們審閱並提供意見。他們的回饋幫助很大。但在某個時間點,我需要有人退一步,重新審視整本書,這就是最近這些審閱者進來的地方。目前我正在處理四位審閱者的意見:William Chargin、Michael Hunger、Bob Martin 和 Bill Wake(他也參與我的持續審閱小組)。

我喜歡逐章處理,先看第一章,查看每個人的意見,然後針對該章節處理所有意見。「處理」的意思是閱讀每則意見,並決定如何處理。每則意見都是審閱者的觀點,有些意見可能會指出建議的變更,可能是表達某件事不清楚,也可能是程式碼錯誤。我常常不會對意見做出任何反應,我可能會不同意某人的建議,可能是因為我覺得這超出了本書的範圍。Michael(他之前也審閱過我的書)提供許多關於其他資料的建議,這些資料需要花好幾年才能追蹤,所以我必須讓大多數建議都過濾掉。但我並不介意,因為有時這些建議是真正需要納入的內容,我很高興有人催促我將它們納入。

錯誤是最明顯需要修正的地方,而當審閱者找出細微的程式碼錯誤時,我總是感到很驚訝。我透過自動化程式碼匯入系統避免許多錯誤,但自動匯入系統有漏洞,而它們已經幫我避免了一些尷尬的錯誤。Michael 在這方面特別擅長,他一定在他的濕件中安裝了幾個編譯器,這就是我認為他是一位優秀審閱者的原因之一。不過 William Chargin 正在挑戰他,所以我感到特別幸運。

釐清通常是最難理解的。有時審查者只會說「我不懂」,有時會比較間接 - 他們會建議一些暗示他們不懂我在說什麼的事情。處理這些很難,因為我必須判斷這只是偶發事件,還是更深層的問題。人們總會對書中的某些部分有困難,試圖解決每個個別的困難將會是得不償失 - 這本書必須大得多,而且散文會變得如此生硬,以至於閱讀起來很乏味。當多位審查者遇到相同困難時,這會有幫助,這樣我就可以確信這是需要我修正的事情。一個例子是我在開頭範例中排列巢狀函數的方式讓小組中的三位感到困惑,所以我曉得我必須嘗試不同的方法。

我總是比較喜歡處理審查意見。對於我所做的事情是否有意義,得到一些回饋是很好的。這個階段特別好,因為它也迫使我退後一步。將近兩年來,我一直在研究細節,一章一章地撰寫。現在我可以整體來看待材料,但仍然可以深入探討以理出重要的細節。

重構採用紅與黑(2018 年 4 月 5 日) 

當我寫《重構》的第一版時,它進入了艾迪生衛斯理的物件技術系列。我從未認真看待書籍系列,所以我只是遵循編輯的建議。從那時起,我成立了自己的系列(「簽名系列」),並投入相當多的精力來策劃它,所以它只包含我堅決推薦的書籍。因此,這本書移到我自己的系列中是很自然的。

然而,這並非不可避免的決定。這個系列並非包羅萬象,而是關於我認為是程式設計技術方面的基礎書籍。我提交了我最近的書《NoSQL 精華》給這個系列,但我拒絕了 - 因為我不認為它符合這個系列的風格。這聽起來相當複雜,但這裡有一個流程。提交給這個系列的每本候選書籍都會寄給這個系列中的所有作者,並且我會徵求他們的意見。在那個案例中,他們幫助我決定拒絕我自己。這次他們覺得這很容易納入,這強化了我的感覺,認為它很合適。

審查更新暫停(2018 年 4 月 6 日) 

正如我在早先備忘錄中所說,我很享受審閱評論。然而,我即將暫停這項工作。我即將出差,這意味著今天是我在五週內最後一次坐在辦公桌前。雖然我在出差期間在技術上可以做一些寫作工作,但我大多會忙於其他事情,無法投入太多精力。(期間還有一些假期,我希望這能讓我恢復一些元氣。)這是一個令人沮喪的休息,因為我真的很想確定這本書的文字,以便更好地專注於其他事情。我希望到現在已經處理並應對了所有審閱評論,但寫作計劃比軟體開發計劃好不了多少(原因大致相同)。

回到我的辦公桌(2018 年 5 月 18 日) 

這週是我在出差五週後終於回到新英格蘭的辦公桌前。這段時間很漫長,但我不能抱怨太多,因為最後幾週在克羅埃西亞度過了一個美好的假期。亮點包括斯普利特、杜布羅夫尼克、帕克萊尼察國家公園,尤其是普利特維采湖群國家公園

我希望在我離開前完成這本書的文字,但仍有一些審閱評論需要處理。在我離開前,我也收到了最後一批評論。所以這週我對最後一批評論進行了第一次審閱,現在只剩下審閱中未完成的待辦事項。壞消息是,所有這些待辦事項都需要一些精力來修復,因為在我審閱評論時無法快速修復它們,所以它們變成了待辦事項。好消息是我只有 14 個待辦事項。我希望在再次出差前,在接下來的兩週內完成它們。

這週關於這本書的另一個主題是開始考慮封面。核心封面設計已經確定,因為它將成為我的簽名系列的一部分,但這意味著我必須選擇一張橋樑照片。我們現在正在著手解決這個問題,希望我能夠在下週分享。

重新製作範例(2018 年 5 月 25 日) 

與上週一樣,這週我都在處理審查意見,以便在開始製作流程前完成書籍的技術內容。上週我已審閱所有意見,處理所有可以在一小時內處理完畢的簡單意見。剩下的都是複雜的意見,在遊戲的這個後期階段處理這些意見相當有壓力,而且(坦白說,有點自找的)期限就在眼前。

這週工作的核心是重新修改兩個範例。兩個範例都讓幾位審閱者覺得難以理解,所以我需要想出一些方法讓範例更容易理解。這不只是修改文字,還包括重新修改程式碼。我認為程式碼範例是我寫作中最困難的部分之一。我試著建立範例,讓範例的複雜度剛好足以說明重點,但不會再更複雜。這些範例仍然是人為簡化的,任何實際的範例對大多數讀者來說都太難理解了,但我希望這些範例能與讀者的日常經驗產生共鳴。今天我花了一整天想出一個約五十行程式碼的範例。我認為這個範例表達了我想表達的意思,但隨著我對這個程式碼進行說明,並觀察我的文字如何與程式碼搭配,我會學到更多。我樂觀地認為這個範例會奏效,但仍有許多不確定性。

早期的範例特別棘手,因為它是較大重構範例的一部分,是本書未來的開場範例。這個範例分為三個階段,審閱者指出中間階段有問題。我重新修改重構的順序,希望現在清楚多了。有趣的是,這個重構以一個重構(拆分階段)為中心,而我在寫開場範例的第一個草稿時還沒寫過這個重構。變更的重點是遵循這個新重構現有的機制,我很高興看到遵循這些機制似乎讓重構變得更容易執行和理解。我書中的機制部分並非重構的唯一機制,而且它們無法在所有情況下都發揮最佳效果。我的目標是讓它們在大部分時間都能發揮良好的作用。因此,我很高興遵循這些機制幫助我完成了這個範例。

重新修改這樣的重構範例讓我非常熟悉 git。我喜歡讓所有程式碼範例保持「即時」,這樣我就可以變更程式碼、執行測試以確保程式碼仍然運作,並標記程式碼的部分以自動流入書本文字中。我已經用程式碼範例這樣做了很多年,讓我的生活輕鬆許多。但用在重構上時會很棘手,因為我有一連串要變更的程式碼。為了應對這個問題,我將重構順序儲存在 git 儲存庫中(必須與儲存書本文字的儲存庫分開),並將重構擷取為一連串提交。然後,我將程式碼匯入書本文字中,並加上標籤以指出提交的參照和程式碼片段的名稱。在重新修改一連串這樣的重構時,我做了很多 cherry picking,也就是變更提交 master~7,然後 cherry pick 自此之後所做的所有重構變更到已變更的提交中。當這個方法運作良好時真是太棒了,即使運作不順利,也比我處理本書第一版時好太多了。

在宣告「完成」之前,我還有最後一週的時間坐在書桌前。目標看來仍可達成,儘管很大程度取決於我今天寫的五十行,以及我寫的重構步驟是否可行。

已發布至製作(2018 年 6 月 1 日) 

五月底,我達成了出版商所謂的「發布至製作」這個重要里程碑。在傳統出版時代,這表示作者將手稿交給製作團隊。在這個階段,我們預期書本的核心內容不會有重大變更。變更會有的:書本進入校對階段時,以及編製索引等事宜時,但這些變更不會影響書本的精髓。

在我早期的書中,我會將電子檔案傳送給 Pearson,然後在稍後收到校對編輯標示變更的巨大列印本。除了檢閱這些變更,看看我是否同意之外,在書本上架之前,我幾乎沒有其他事可做。現在,這個流程更具互動性,校對編輯和我會共用一個 git 儲存庫,而我會檢視差異,看看他建議的變更。但跨越重要橋樑的感覺依然存在。我不會再修改任何範例,或新增任何重要資料。在某種程度上,這本書已經完成了。(儘管這是一本網路優先的書,我打算繼續發展它的網路呈現方式)。

我感到如釋重負,儘管這本書仍有許多事要做,這仍然是一個重要的里程碑,表示我對這本書的關注將開始減弱。我沒有太大的解脫感,因為我必須在下週前往馬德里進行幾場演講,而對我來說,演講行程的吸引力還不如去看牙醫。但這的確減輕了我心裡的負擔。

新封面(2018 年 6 月 13 日) 

當我們開始製作簽名系列時,封面設計師規劃了基本設計,其中包含了每本書不同照片的空間。我決定這些照片應該遵循該系列所有書籍的主題。當時我的妻子,一位結構工程師,正在設計橋樑;她後來從水平(橋樑和隧道)轉向垂直(建築物)。她參與橋樑的設計激勵我將它們用作本書的共同主題。因此,每當一位作者在我的簽名系列中寫書時,我都會請他們選擇一座橋來裝飾封面。理想情況下,這座橋應該與他們有一些個人聯繫。

對於我在該系列中的第一本書(企業應用架構模式),我選擇了波士頓的扎金橋。連結相當清楚 - 他們在同幾年建造了這座橋,就在我寫這本書的同幾年。對於我的第二本系列書籍(特定領域語言),我選擇了鐵橋 - 這是與我長大的黑鄉的連結,也是一座具有歷史意義的橋樑。

那麼,要為重構書籍選擇什麼呢?我想到的一個想法是,如果我可以在重構和橋樑工程之間畫出某種類比 - 但與我認識的橋樑工程師討論後,很明顯橋樑工程中沒有任何東西可以與重構相提並論。因此,我的想法轉向非專業協會。在這種情況下,我開始思考我在新英格蘭居住的二十多年來多次拜訪過的最喜歡的地方之一 - 阿卡迪亞國家公園。這立即建議選擇馬車道上的許多有吸引力的橋樑之一。

但我還想到了另一個阿卡迪亞的可能性。在前往阿卡迪亞的路上,我們會穿過佩諾布斯科特河。在我寫第一本重構書籍時,這條道路使用沃爾多-漢考克大橋穿過佩諾布斯科特河,這座橋是著名的橋樑工程師大衛·斯坦曼設計的吊橋。然而,在新世紀的頭幾年,他們發現這座有 70 年歷史的橋樑需要更換,到 2007 年,這條道路已經經過新的佩諾布斯科特海峽大橋

在我們前往阿卡迪亞的其中一次旅程中,我們停下來,這樣我就可以拍兩座橋的照片。我很高興我們最後這樣做了,因為一年後,沃爾多漢考克大橋被拆除了。(很可惜我是在如此陰霾的日子拍下照片的。)

photo used for cover

儘管我無法在橋樑工程和重構之間找出任何類比,但我可以強迫自己找出重構書籍的兩個版本和這兩座橋之間的創意類比。

儘管各種推特用戶評論說重構書籍的第二版「重構」了第一版,但這並非事實。(的確,就像橋樑工程一樣,我不認為從重構到寫作有任何類比。)這個第二版是舊版的替代品,就像佩諾布斯科特海峽大橋取代沃爾多漢考克大橋一樣。沃爾多漢考克大橋展示了創新技術,降低了橋樑建造成本,同樣地,重構書籍描述了一種新的技術,可以降低建構軟體系統的成本。這本書的第一版由我簽名系列中的新版本取代,而新的佩諾布斯科特海峽大橋的設計類似於扎金大橋,那是該簽名系列第一本書的封面大橋。

兩種讀者(2018 年 6 月 27 日) 

在建構軟體時,從使用者的角度思考軟體非常重要。因此,我們有建立角色的概念,並使用這些角色來幫助引導軟體系統的功能和使用者體驗。同樣地,對於書籍來說,思考我的讀者並對應當引導我寫作的角色有一些概念很重要。

寫作最明顯的角色是學生讀者 - 他對書中的主題幾乎或完全沒有知識,並且正在閱讀這本書來學習材料。這是我的主要角色,我盡力了解這個讀者腦中的想法,以及如何最好地向他傳達資訊。

但還有一個第二個角色也很重要 - 老師。這個角色已經知道書中的大部分(如果不是全部)材料。她使用這本書來幫助指導較資淺的開發人員。基本上,這本書是她幫助她改善團隊技能的工具。

有時她可能會直接使用這本書,告訴初級人員他需要將特定類別更改為值物件,從而使用將參考變為值重構。在更高的層面上,她可能會專注於一個異味。我聽過的一種技術是團隊負責人指定「本週異味」,並讓團隊找出並修復該異味的範例。這既改善了程式碼,也教導開發人員如何發現並修復類似的問題。

即使這本書沒有被直接使用,我希望它仍然可以間接地派上用場。一位資深開發人員可能具備重構的知識,但这並不意味著她知道如何教授它。教授一個主題本身就是一項技能,在某種程度上獨立於對一個主題的知識或執行任務的技能。我經常遇到一些有天賦的從業者,他們不太擅長向他人教授他們所做的事情。一本好書可以幫助這些領導者展示如何解釋一個主題。將參考變更為值的部分的機制並非執行重構的唯一方法,但遵循這些步驟可以讓一位熟練的同事更容易向新人展示如何執行此操作。

像這樣的第二版的有趣後果是,大多數對這本書感到興奮的人是教師讀者,而不是學生讀者。教師很可能在多年前就是第一版的學生讀者。如果您是這樣的讀者,請記住這本書不會教您有關重構的任何新知識。如果它教會您任何東西,那就是如何將其教授給您所領導的人。當您評估這本書對您是否有用時,並不是因為您可以從中學到什麼,而是它如何幫助您加速身邊人的學習。

一些隱藏的英雄 (2018 年 7 月 10 日) 

我認識的所有技術書籍作者都提到了他們對技術審閱者的巨大債務。我們都寫過有重大缺陷的作品,這些缺陷被擔任審閱者的同行發現。我沒有做很多技術審閱工作,部分原因是我認為自己不太擅長這方面,因此非常欽佩那些承擔這項工作的人。審閱別人的書甚至沒有什麼好處,所以把它當作一種慷慨的行為來做。

當我開始認真寫這本書時,我組建了一個顧問郵件清單,以便給我反饋。隨著我的進展,我把新材料的草稿發給這個小組,並請他們提供反饋。我要感謝以下人士在郵件清單上發布了這樣的反饋:Arlo Belshee、Avdi Grimm、Beth Anders-Beck、Bill Wake、Brian Guthrie、Brian Marick、Chad Wathington、Dave Farley、David Rice、Don Roberts、Fred George、Giles Alexander、Greg Doench、Hugo Corbucci、Ivan Moore、James Shore、Jay Fields、Jessica Kerr、Joshua Kerievsky、Kevlin Henney、Luciano Ramalho、Marcos Brizeno、Michael Feathers、Patrick Kua、Pete Hodgson、Rebecca ParsonsTrisha Gee。

在這個小組中,我特別想強調我從 Beth Anders-Beck、James ShorePete Hodgson 那裡獲得的關於 JavaScript 的特殊幫助。

一旦我有一個相當完整的初稿,我將其發送出去進行進一步審查,因為我希望有新的觀點來審視整個草稿。William CharginMichael Hunger 都提供了令人難以置信的詳細審查意見。我也從 Bob MartinScott Davis 那裡得到了許多有用的意見。Bill Wake 除了在郵件列表上提供他的貢獻外,還對初稿進行了全面審查。

我發現郵件列表的增量審查和最終的完整審查相結合的方式非常有效。將所有審查留到最後(就像我的早期書籍,包括第一版的情況一樣)導致我太晚收到有用的意見。我能夠接受早期的意見,並在繼續寫書時對它們做出反應。最終的審查仍然很有幫助,因為增量審查者很容易失去書籍的整體脈絡——事實上,當我深入研究時,我也很容易失去這種脈絡。讓新的觀點審視整體會產生很大的不同。

完成校對(2018 年 7 月 25 日) 

我剛剛完成審查重構的校對。這是我的完美散文被發送給某人檢查它是否像我想像的那麼精彩,並發回更正清單的階段。在我的情況下,清單相當長。

作者對校對過程的反應方式差異很大。如果他們完美文字中的單個字元被更改,一些作者會勃然大怒。其他作者對手稿感到厭煩,以至於他們揮手通過所有更改。我傾向於後者,但仍然會審查每一處更改——主要是為了確保校對人員沒有無意中更改文字的含義,這對於如此技術性的書籍來說是一個真正的危險。

我發現這個審查既有趣又令人沮喪。它令人沮喪,因為到這個時候我已經真正完成了文字,不想再讀它了。許多校對對我來說似乎相當武斷——以對我來說似乎沒有顯著差異的方式更改一些標點符號或措辭。例如,我從未真正理解分號的意義,所以幾乎從不使用它們。但像這樣的校對更改是為了讀者,而不是為了我。我目前的校對人員 Dmitry Kirsanov 說:“校對(當它不僅僅是糾正糟糕的語法時)是一個語調問題。作者並不總是能聽到自己的語調,就像我們不能正確地聽到自己的聲音,並且經常(通常是不愉快地)在錄音中聽到自己的聲音一樣。”

作者對編輯的反應不一,但不同的編輯也做著不同的工作。我欣賞與我合作的第一位稱職編輯,因為她認為盡可能保留作者的聲音至關重要。我對她工作的最主要印象是加了很多逗號,不出所料,除非我認為真的需要,否則我不會加逗號。遺憾的是,我無法在自己的書中使用她,因為她是英國人,而美國出版商認為英國人不可能按照美國標準進行編輯。Dmitry 是我最後兩本書的編輯,我也很喜歡他的工作。儘管他的許多修改讓我聳肩,但其中許多對我的措辭都有明顯的改進(包括這句話中的一個)。有時候,他會突然做出一些比我更像我的改變,這既令人毛骨悚然又美妙。

我遇到的一些編輯會強調他們如何更改文本以使其正確,這種態度確實讓我翻白眼。畢竟,許多「正確英語」的規則都是 19 世紀發明的慣例,用於區分受過良好教育的上層階級人士和我這樣的平民百姓。(例如,分裂不定詞規則僅僅是為了模仿拉丁語。)

在幾種情況下,我看到一位編輯編輯了已經由另一位編輯編輯過的文本,並最終做出了與他們對未編輯文本所做的修改一樣多的修改。(我感到沾沾自喜。)

此網站未經編輯,您會看到我的原始文本。我沒有看到太多關於它的抱怨,因此我很樂意跳過編輯階段,享受這種便利。

精簡印刷版(2018 年 8 月 7 日) 

在我為第二版所做的所有更改中,最重要的是我將其寫成一本以網路為優先的書籍。我的意思是,這本書的正規表示形式存在於網站上,凌駕於書籍的其他表示形式之上,例如印在紙上的那些。Pearson 正在設定一些事項,以便當您獲得實體書時,您就能夠向 Pearson 註冊並獲得該書的網路版本。作為書籍的次要表示形式,紙質版本將包含較少的內容。此外,我希望未來在書籍的網路版本中添加更多材料,當然紙質版本無法更新。

幾個星期前,我必須決定哪些內容會出現在紙本書中,哪些內容只會出現在網路版本中。我為自己設定的一個限制是,本書的第二版不會比以前的版本更大。(這也是我為自己設定的 UML 精華的規則。)我這樣做的原因是,我發現第二版有膨脹的危險。我可以理解為什麼,畢竟作者對某個主題有了更多了解,並希望將所有新東西都放進去,但一本更大的書通常不是一本更好的書。由於重構遵循雙工形式,並且主要是一個參考目錄,因此增加大小不應該是一個大問題,但我仍然不信任一本大而實體的書,所以我保留了這個限制。

第一版時鐘顯示 412 頁(不包含參考和索引),因此我將其設定為我的目標。我們進行了初步的頁面校對,而新書有 440 頁,因此我需要至少刪減 28 頁才能符合我自訂的限制。當我開始找出要刪減的部分時,我對於選擇感到非常擔心,但我鬆了一口氣,因為這比我擔心的還要容易。

我在新書中有 63 個重構,我將它們分為兩個優先順序等級。然後,我採用較低優先順序的重構,並尋找書中其他地方未引用的重構。這找出包含 19 頁的五個重構 - 我可以很輕鬆地從印刷版中移除這些重構。當然,我還有另外 9 頁要處理。我可以移除更多重構,但相反地,我注意到了需要十頁的範例。這是拆分階段重構的第二個範例,是一個不錯的範例,但並非絕對必要,因為我已經有一個範例了。此外,這個第二個範例是我早期在 Java 中完成的,而且不想用 JavaScript 重寫。這將會是印刷書中唯一的 Java 範例,因此移除它可以移除看起來很奇怪的東西。

我們使用這些刪減重新編排了這本書,結果變成 410 頁。因此,雖然算術沒有完全正確,但我符合我設定的限制。(我也應該重申:這五個重構將提供給所有書籍擁有者,你只需要前往網站查看它們,而不是在紙本上查看它們。)

我了解一些讀者可能會想知道,那五個重構受害者是什麼?我稍後會說明 - 到目前為止,我尚未說明第二版中有哪些重構,也未說明所有第一版重構的命運。我稍後會在備忘錄中說明所有這些。

這最後兩週非常忙碌,因為我必須爭取完成書籍製作的幾項任務。我原本希望很快就能結束這本書的工作,但現在我接受了還有很多事情要做,部分是為網路版做準備。我也會在稍後的備忘錄中說明所有這些。

撰寫印刷書(2018 年 8 月 24 日) 

在過去的幾週中,我在重構書上的工作重點在於整理印刷書的各種未完成事項。我們現在已經到了製作工作現在由 Alina Kirsanova 負責的階段,她會整理書籍的組成,以及進行校對。撰寫一本書意味著要注意每一頁的外觀,而且會在分頁周圍出現各種問題。

我在寫作時,不會太擔心分頁。我現今發表的寫作大多在網路上,因此我不必考慮實體頁面。但實體頁面對於書籍來說很重要。範例問題領域是程式碼範例。我不希望程式碼範例中出現錯誤的分頁,理想狀況下,我希望我仔細撰寫的小函式不會跨頁。因此,Alina 會檢視每個頁面,確保分頁出現在正確的位置。為了支援這一點,我需要調整程式碼範例的自動匯入,讓她可以在需要時插入分頁。

行長也是她注意的事項。當我檢視我的原始檔時,現在會看到新的 XML 標籤:例如 <dk:nobr>clarity</dk:no-br>,用來表示我們不希望在兩行中拆分的文字。這是使用 XML 而非 markdown 作為原始文字的優點之一 - Alina 可以輕鬆為文字新增新的標記,而我的工具鏈可以傳遞給她的工具鏈。

我也準備了參考頁面:填寫書目,並為內頁封面產生重構和氣味的表格。接下來我必須檢視頁面的最終校樣,並處理 Alina 提出的一些組成問題。許多作者偏好交出他們的稿件並就此打住 - 我現在肯定能體會這種做法。但參與這項工作的優點之一,就是我可以欣賞書籍組成的細心工作。

Safari 上提供粗略剪輯(2018 年 8 月 29 日) 

訂閱 Safari 線上書籍服務的人現在可以取得 第二版的粗略剪輯。這已經過文字編輯,但尚未校對或進行最終組成。

大多數人會對第二版感到失望(2018 年 8 月 30 日) 

當我接近發行新書時,我的感覺通常是興奮和恐懼的混合。興奮是因為我將花費數月或數年時間製作的東西發布到世界上,而且我很想看看人們如何回應它。恐懼是因為我將花費數月或數年時間製作的東西發布到世界上,而且我擔心人們如何回應它。人們會喜歡它嗎?所有這些工作是否值得?

對於這本第二版,我的感覺比較像是接受大多數人會感到失望。

這並不是因為我不認為自己在這本書上做得很好。就像我所有的寫作計畫一樣,我投入了許多心力與精力。我想,這本書是我最自豪的作品,而這本書的成果是值得的。但即使如此,我預期這本書會引起負面的反應。這是因為熟悉第一版的人自然會將它與第一版比較,而大多數人會發現新版有待加強,儘管我認為自己已經改進了它。

人們熟悉第一版,已經習慣了它的缺點,並且喜歡我決定更改的原始元素。我們知道,損失規避意味著人們對失去某物的感覺是獲得相應收益的兩倍。因此,新版本中的任何改進都必須比任何感知到的缺點好上兩倍,我才有可能打平,而這是一個很難達到的目標。

除此之外,許多人不會將這本第二版與第一版進行比較,他們會將它與他們想像中的第二版進行比較。通常,這些想像是不切實際的,我有許多想法在我的腦海中聽起來不錯,但當我試著將它們寫下來時卻行不通。即使堅持現實的,它們也有很多。最後,我必須選擇一條路,即使我選擇了最受歡迎的路,它們的分歧也很大,因此它仍然只能符合少數意見。

(我懷疑我這裡的感覺與其他作者相同,這也許可以解釋為什麼這麼多人在修訂版或多卷作品的後續部分中掙扎。)

既然這個失望是不可避免的,為什麼我還要費心做第二版?(我在過去幾年中多次問自己這個問題。)答案是,對這個新版本的真正判斷並非在它發行後的幾個月內的立即反應。相反,它是否能幫助人們在五年、十年、二十年後了解重構。大多數這個版本的目標受眾甚至還不知道這本書,許多人還沒有寫過程式,大多數人永遠不會關心第一版。對這些讀者的影響是衡量這項努力是否值得的考驗。遺憾的是,在未來幾年內,我才能評估我在過去幾年中勞動的價值。

已送印(2018 年 9 月 28 日) 

第二版的檔案已於今日寄送至印刷廠。這代表我們已完成製作印刷版的全部工作。再次感謝艾琳娜·基爾薩諾娃,她編寫了這本書、進行校對(發現了一些特別令人尷尬的錯誤),並編製了索引。來自皮爾森的茱莉·納希爾是本書的製作編輯,負責協調所有這些製作工作。

我們預計印刷書籍將於 10 月底或 11 月初出現在皮爾森的倉庫中。它們應該會在不久後進入零售通路。

但網路版本可能會出現一個小問題。我們不希望印刷版在我們整理好網路版本之前出現,而我沒有太多時間整理。我休了兩週假(在康瓦爾郡健行、在倫敦看戲、和朋友玩遊戲,以及享用一些令人愉悅的奢華美食),現在接下來兩週有幾趟商務行程。我現在已經整理好網路版本大部分的管道元素,但要到 10 月中旬才能開始正式進行。希望它不會花太多時間完成,但我之前沒有做過,所以我不知道會出什麼問題。除了它是軟體,而我們都知道軟體有多好預測!

處理網路版本(2018 年 10 月 20 日) 

幾週前的最後一次更新中,我提到這本書已經送去印刷,他們大概正忙著印刷。從那時起,我的首要任務就是完成網路版本。雖然所有寫作都已完成,我仍必須準備檔案並進行版面配置。我無法立即開始,因為我必須參加 Thoughtworks 的幾次會議:在亞特蘭大決定下一個雷達,以及在北京舉行的全球管理會議。

但這週我已經回到辦公桌,可以再次處理這本書。第一個任務是了解網路版本如何發布。皮爾森有一個網路書籍檢視器,它基本上會取得一個 epub 資料夾,並透過一個簡單的網路應用程式將其投影出來。這項功能的好處在於,大部分的書都是我熟悉如何產生的網頁(事實上,這是我在寫書的大部分時間裡檢視書的方式)。不過我確實必須整理出各種所需事項,包括產生適當的 epub 清單檔案,以及修正那些在網頁環境中有效但不在 epub 環境中有效的項目。

在基本架構完成後,我需要套用正確的 css,以執行一些動作,例如確保已刪除的程式碼正確標記為刪除線、產生目錄和重構清單。有一些有趣的複雜情況,例如發現我用來突顯程式碼的 span 類別名稱被檢視器用於其他用途。

不過現在我已經接近完成(我的 org 模式核對清單顯示已完成 9/13 項工作),因此對於網路版本將在我們從多倫多的「典範轉移」研討會返國後不久的下一週完成感到相當滿意。這表示我們將能夠在書籍從印刷廠回來後不久開始販售實體書。

不過我仍然沒有完成。下一個工作是修改 refactoring.com,特別是目錄,並使用新的重構更新它。我也想彙整一份網路版本中,但印刷書中沒有的清單

(我通常不喜歡說「幾乎完成」之類的話,但我已經一段時間沒有寫任何進度筆記,而且覺得我欠大家一個更新。)

書籍已印刷(2018 年 11 月 19 日) 

關於書籍最新進度的快速更新。書籍已印刷並運往 Pearson 的倉庫。我已完成網路版本的檔案,但我們需要在 Pearson 的基礎架構上測試它們。一旦完成,我們就可以釋出書籍供人購買。我們希望在下週初在 InformIT(Pearson 的網站)上啟用。亞馬遜應該會緊接在後。感恩節可能會造成一些延誤,所有那些火雞塞爆了供應線。不過我會在得知更多資訊後讓大家知道。

在 informit 上釋出(2018 年 11 月 26 日) 

在感恩節期間,重構在 informit 上釋出。現在您可以在那裡直接訂購實體書和電子書。實體書正在運往亞馬遜,他們應該會在下週左右開始配送。亞馬遜的 kindle 版本應該會在那時左右出現。其他書店應該會在不久後收到他們的副本。書籍應該會逐漸送到國際賣家手中,但我不知道這需要花多久時間。

最新備忘錄:與書面對面

2018 年 12 月 10 日

face to face picture

過去幾週我都在歐洲,因此錯過了重構送達家中的時間。現在我回來了,我終於可以看到真正的書了。即使當了這麼多年的作者,看到實體書仍然令人興奮。

這本書真正讓我印象深刻的第一件事是,與第一版相比,它有多麼

photo of first and second edition spines

這並非頁數大幅減少的結果(新版的頁數為 416 頁,而舊版為 430 頁),而是紙張變薄了。當我打開它時,我驚訝地發現它是彩色的。顯然這並不令人意外,但它仍然令人驚訝,因為它是我的第一本以彩色印刷的書。這對於本書特別有用,因為它使我能夠更好地突出重構過程中發生的變化。