“軟件開發教父”Martin Fowler 從業 40 年最想說這兩個字

“軟件開發教父”Martin Fowler 從業 40 年最想說這兩個字

作者 | 異步社區

本文經授權轉載自異步社區(ID:epubit)

Martin Fowler,世界級軟件開發大師,敏捷開發的開拓者和創始人全球知名的面向對象分析設計、UML、模式等專業領域的領頭羊,首創敏捷開發方法論,被譽為軟件開發“教父”,現任職於全球知名技術諮詢公司ThoughtWorks,首席科學家。

“软件开发教父”Martin Fowler 从业 40 年最想说这两个字

Martin Fowler

坊間流傳著這樣一句話,如果有一本編程技術類書籍能夠讓讀者在工作或實踐多年後,還在反覆咀嚼玩味、愛不釋手、引導著讀者前進著,那個必定是Martin Fowler的《重構》。

Martin還是IT領域的知名作家,他撰寫的七本有關軟件開發的書廣受程序員們的喜愛,包括重構、企業應用程序體系結構模式和UML Distilled等領域。其中《重構》風靡國內外,擁有數百萬讀者,國內豆瓣評分高達9.5分。

“软件开发教父”Martin Fowler 从业 40 年最想说这两个字“软件开发教父”Martin Fowler 从业 40 年最想说这两个字

Object Technology International, Inc,Erich Gamma 曾這樣評價Martin:

Martin Fowler清楚地揭示了重構過程,他為面向對象軟件開發所做的貢獻難以估量。他解釋了重構的原理和最佳實踐,並指出何時何地你應該開始挖掘你的代碼以求改善。

因此,我極力推薦你試試Martin Fowler的重構手法,你和你的程序都將因此更美好。

“软件开发教父”Martin Fowler 从业 40 年最想说这两个字

軟件開發“教父”的重構生涯

Martin Fowler,1963年出生在英格蘭的沃爾索耳,正是編程世界剛剛起步的年代。

Martin 在80年代初開始接觸軟件行業,那時候Smalltalk還是一門很火的語言,大家都在學習這門語言,而Martin也剛開始從事軟件工作——關於信息系統對象建模方面的顧問。

那個年代沒有任何有關面向對象分析和設計的書籍,大家都是用一種簡單的圖符表示法,然後提出一個簡單的建模過程,最後用幾個簡單的示例來加以說明。但Martin認為不應該把重點放在過程——即如何建模,而是把重點放在過程的結果——即模型本身,儘管這與當時大環境下的創建方式是相悖的。

“软件开发教父”Martin Fowler 从业 40 年最想说这两个字

到了90年代初,Martin發現,大多數程序員很難通過緊跟技術創新的腳步來享受軟件工程領域的新成果。

身為一個信息系統對象建模顧問, Martin從Smalltalk上學得的專業知識是遠遠超過這個職業所需要的,他覺得自己既然有了這些建模方面的理念,同時又對編程方面很感興趣,所以他不單在建模方面幫助別人,還在編程方面進行指導——藉助外力的幫助,精確地運用UML。

“软件开发教父”Martin Fowler 从业 40 年最想说这两个字

從建模到編程語言,他把這些都看成一件完整的、而非毫無關聯的事。

這樣的工作持續了近十年,1999年,Martin迎來了他人生中意義重大的一年。

那時Martin造訪了客戶調研的開發項目時發現,該系統的核心繼承體系相當凌亂,為此,他建議負責該項目的經理將這些代碼進行整理,但是項目經理認為在項目面臨很大的進度壓力下,只要程序看上去還可以運行就算是完成。

這種情況下,《重構:改善既有代碼的設計》面世了,Martin在這本書中揭示了重構的過程,解釋了重構的原理和最佳實踐方式,並給出了何時以及何地應該開始挖掘代碼以求改善。

重構這個理念一經推出,受到了廣大程序員的喜愛,他們覺得在不改變代碼外在行為的前提下,對代碼做出修改,以改進程序的內部結構是一個非常妙的事。後來,這本風靡國際IT行業的《重構》被引入國內,在豆瓣評分以9.2的高分長期霸屏程序員必讀書單中。

2010年,第五屆敏捷軟件開發大會“敏捷中國2010”上,Martin的“敏捷宣言”又一次引領了整個IT行業對敏捷開發的認識,從此“敏捷”二字開始風行國內 IT 領域。對程序員們來說,他就是當之無愧的先行者。

“软件开发教父”Martin Fowler 从业 40 年最想说这两个字

Martin Fowler

就在去年,這位先行者又全面升級了《重構》,《重構:改善既有代碼的設計(第2版)》面世了,國內外掀起一陣搶購熱潮,豆瓣評分更是高達9.5分。

“软件开发教父”Martin Fowler 从业 40 年最想说这两个字

Martin定義的重構到底是什麼?

說起重構,還要從1999年發生在Martin身上的一件事說起。面對凌亂的系統的核心繼承體系,他建議負責該項目的經理將這些代碼進行整理,但是被項目經理拒絕。

隨後,Martin把自己的想法第一時間告訴了在這個繼承體系上工作的程序員,程序員都很敏銳, 馬上就看出問題的嚴重性,特別是在這種需要藉助外力才能發現問題。他們立刻用了兩天的時間整理好這個繼承體系,並刪掉了其中一半代碼,功能毫髮無損,而且發現在繼承體系中加入新的類或使用系統中的其他類都更快、更容易了,他們十分感謝Martin。

但項目經理很不高興,他覺得這些程序員卻白白耗費了兩天時間,做的工作卻與未來幾個月要交付的大量功能毫不相干,明明原先的代碼運行起來還算正常,為什麼要為了可能發生的問題去花費時間提前預防呢?

不過在6個月之後,這個項目還是宣告失敗了,原因是代碼太複雜,無法調試,也無法將性能調優到可接受的水平。再後來,這個項目重新啟動,唯一的解決辦法就是從頭開始編寫整個系統,Kent Beck 受邀做了顧問。他做了幾件迥異以往的事,其中最重要的一件就是聽從Martin的建議,堅持以持續不斷的重構行為來整理代碼。

那時,Martin第一次認識到重構的重要且不可替代性。

“重構”這個概念最開始來自於 Smalltalk圈子,由於重構是框架開發中不可缺少的一部分,所以當框架設計者討論自己的工作時,這個術語就誕生了。

當他們精煉自己的類繼承體系時,當他們叫喊自己可以拿掉多少多少行代碼時,重構的概念慢慢浮出水面,後來重構就進入了其他編程語言陣營之中。

說得直白一點,所謂重構(refactoring)就是這樣一個過程:在不改變代碼外在行為的前提下,對代碼做出修改,以改進程序的內部結構。

重構是一種經千錘百煉形成的有條不紊的程序整理方法,可以最大限度地減小整理過程中引入錯誤的概率。本質上說,重構就是在代碼寫好之後改進它的設計。

“在代碼寫好之後改進它的設計”這種說法有點兒奇怪。在軟件開發的大部分歷史時期,大部分人認為,應該先設計而後編碼:首先得有一個良好的設計,然後才能開始編碼。

但是,隨著時間流逝,人們不斷修改代碼,於是根據原先設計所得的系統,整體結構逐漸衰弱。代碼質量慢慢沉淪,編碼工作從嚴謹的工程墮落為胡砍亂劈的隨性行為。

而“重構”正好與此相反。

哪怕手上有一個糟糕的設計,甚至是一堆混亂的代碼,我們也可以藉由重構將它加工成設計良好的代碼。重構的每個步驟都很簡單,甚至顯得有些過於簡單:只需要把某個字段從一個類移到另一個類,把某些代碼從一個函數拉出來構成另一個函數,或是在繼承體系中把某些代碼推上推下就行了。

但是,聚沙成塔,這些小小的修改累積起來就可以根本改善設計質量。這和一般常見的“軟件會慢慢腐爛”的觀點恰恰相反。

有了重構以後,Martin發現工作的平衡點開始發生變化,例如,設計不是在一開始完成的,而是在整個開發過程中逐漸浮現出來。在系統構築過程中,他學會了如何不斷改進設計。這個“構築-設計”的反覆互動,可以讓一個程序在開發過程中持續保有良好的設計。

Martin認為,重構這東西不可能一開始就完全正確,它將隨著設計者的經驗成長而進化,代碼被閱讀和被修改的次數遠遠多於它被編寫的次數。而保持代碼易讀、易修改的關鍵,就是重構。

“软件开发教父”Martin Fowler 从业 40 年最想说这两个字

作為一本為專業程序員編寫的重構指南——《重構》,Martin的目的是告訴所有程序員如何以一種可控且高效的方式進行重構,從而減少了開發過程中的風險。

書裡提出的重構準則將幫助他們學習如何有條不紊地、一次一小步地修改代碼、改進程序結構,且不會引入錯誤的正確的重構方式,最終得到有效的、長期可運行的代碼程序,而不是去遵循那句古老的工程諺語:“如果它還可以運行,就不要動它。”

“软件开发教父”Martin Fowler 从业 40 年最想说这两个字

重構再度升級

《重構》自1999年面世以來,已經經過21年了。軟件行業裡新的編程語言不斷湧現,老的編程語言也加快迭代,而函數式編程和麵向對象一樣成了主流編程語言的標配。不僅軟件開發技術發生了很多重要的變化,各種軟件開發工具也日益現代化,對開發的更好支持也已成為主流編程語言新的核心競爭力。

而現在, “重構”這一理念已被讀者廣泛接納,作為一種經千錘百煉形成的有條不紊的程序整理方法,能夠最大限度地減小整理過程中引入錯誤的概率,成為編程的詞彙表中不可或缺的部分,《重構》一書至今依舊被無數程序員奉為軟件開發領域的經典之作。

但重構的紮實功夫要學起來、做起來,頗不是件輕鬆的事,且不說詳盡到近乎瑣碎的重構手法,光是單元測試一事,怕是已有九成程序員無法企及,漸漸地,“重構”成了一塊漂亮的招牌,大家都願意掛上這個名號,可實際上乾的卻多是“刀劈斧砍”的勾當。

就國內先如今的情況而論,“重構”概念的表裡分離,大有愈演愈烈之勢。隨著當年的一線技術人員紛紛走上領導崗位,他們樂於將“重構”這塊漂亮招牌用在更寬泛的環境下,例如系統架構乃至組織結構,都可以“重構”一下。

然而基本功的欠缺,卻也一路如影隨形。當年在對象中的刀劈斧砍,如今被照搬到了架構、組織的調整。於是“重構”的痛苦回憶又一遍遍重演,甚而程度更深、影響更廣、危害更烈。

通過重構,現在的程序員普遍通過微增量來開發系統、編寫測試用例。但Martin認為這遠遠不夠,重構的影響其實應該更廣泛,20年前,他和其他先行者鼓勵大家都接受重構這一概念,但是,在整個行業普及重構仍需要相當長的時間。

對於IT領域來說,Martin不僅僅是一個先行者,他還是一個引路者。

Martin希望看到更多人使用他們大力推廣的測試法,使用持續集成和持續交付等方法。但涉及上述概念,Martin覺得自己只能儘量在書中,從主客觀上儘可能詳盡地解釋這些技術,並希望這會說服更多人進行嘗試,“當他們嚐到甜頭後就會在工作中真正用上這些方法“。

“软件开发教父”Martin Fowler 从业 40 年最想说这两个字

改善既有代碼的設計(第2版)》

針對這一現象,Martin推出了《重構:改善既有代碼的設計(第2版)》,他在第1版的基礎上做了全面修訂,反映了編程領域業20年來發生的許多變化,但Martin傳遞的理念也始終如一:不改變外在行為,而提高代碼質量,但將基礎功夫做得更紮實。讓人不禁感嘆於他對“微末功夫”的執著!

很多人好奇Martin為什麼決定將《重構》再版?Martin給出了3個原因:

  • 第1版裡的代碼已經很陳舊了,書裡面還有Java.util.Vector;

  • 一些重構並非是與面向對象緊耦合在一起的;

  • Martin認為Java是一種非常嚴格的面向對象編程語言,而第1版中所有的重構都是基於面向對象的,他想通過再版來說明每個程序員都可以用任何(編程)語言、在任何環境中、遵循書中提到的範例進行重構,這也是他決定再版《重構》的源動力。

Martin認為重構的基本機制不會發生巨大轉變,即使使用面嚮對象語言工作也是如此。他覺得有一等函數很好,可以嘗試許多函數式的理念,例如,寫軟件時大部分函數都具備引用透明性,這在面向對象系統和在函數式系統中都是好事。

所以Martin不像許多人那樣在函數式編程和麵向對象編程間畫出明確界限,他認為兩者有很多共同的地方,未必存在巨大差異。他鼓勵程序員不要有門戶之見,要用綜合理念來解決問題。

對於最新版《重構》,Martin認為有一個重構手法也許值得注意,拆分階段(split phase)。早在幾年前,當Martin和Ken Beck商談拆分階段的時候,Martin第一次意識到這也是重構手法。

通過這種重構手法,Martin將大量計算合理分為兩個階段,使用中間數據結構進行通信。其中一個例子是解析拆分階段可有效地將token從解析中抽離出來,這樣就得到了一個可可保存在存儲器種的token流,可處理相關字符串、文本字符串。

“软件开发教父”Martin Fowler 从业 40 年最想说这两个字

Martin Fowler

而說到重構工具,Martin和Kent做了很多年了,但他們從來沒有意識到工具的重要性;當他們意識到這一點之後,他們感覺重構工具已經無處不在,他們認為這個內容非常重要,然後Martin就真把這些新內容加到新版中了。

重構的關鍵是理念:通過進行最細微的改變,然後將這些變化串聯起來,這就是重構思維核心。將一個大變化拆分為許多小變化,又在儘可能多進行細微變化的同時,不改變系統的整體表現,然後隨時間推移,反覆練習並思考如何進行拆分。Martin在《重構 2》一書中說過,他通過重構框架思考問題的體驗,嘗試各種高效的重構手法並做出決定,最重要的就是通過實踐進行重構。

他認為在嘗試了不同的重構手法後,找出能重構手法生成理想序列,繼而進行嘗試識別出這種重構手法,而同樣的邏輯也適用於更廣泛的層面。

因此,他採用了70多個種可行的重構,並且把每個重構都介紹了一種經過驗證的代碼變換手法的動機和技術。就像軟件開發的大多數工作一樣,重構除了動手做,別無他法,必須反覆實踐,必須在項目中使用重構。

Martin始終希望,重構準則能幫助大家一步步修改自己的代碼,減少了開發過程中的風險。

“软件开发教父”Martin Fowler 从业 40 年最想说这两个字

重構=編碼

在日新月異的 IT 技術世界裡,不變的東西其實還是有的——重構。

從《重構》的英文原版引進國內,到現在已經過去20年了。Martin Fowler 這次對本書進行的重構,體現了近年來編程領域的一些思潮變化,既有設計,又永遠有改進空間。

儘管時間是最強大的重構工具,連書裡的示例語言都從 Java 變成 JavaScript 了,但書中的理念和實踐的價值並沒有隨時間流逝。

重構早就成了軟件開發從業者本能的一部分,每個 IDE 都內置了重構功能,每個程序員都定期重構自己的代碼。

對於軟件工程師來說,重構,並不是額外的工作,它就是編碼本身。切實地讀懂了《重構》的軟件工程師,在能力上都會獲得一個數量級的提升。

參考文獻:

  1. 《分析模式:可重用對象模型》 作者:Martin Fowler

  2. 《UML精粹:一個簡短的指南標準對象建模語言》 作者:Martin Fowler

  3. 《重構:改善既有代碼的設計》 作者:Martin Fowler

  4. 軟件開發教父,Martin Fowler:https://zhuanlan.zhihu.com/p/71216874

“软件开发教父”Martin Fowler 从业 40 年最想说这两个字

☞程序員為什麼應該旗幟鮮明地反對“最佳實踐”?

☞京東:網傳通過 Bug 搶茅臺是假消息;羅永浩回應帶貨價格非「全網最低」;Rust 文檔團隊解散 | 極客頭條

☞紅外光抗疫、成功預測新基建,投資 280 家企業的光學博士到底是誰?

☞前端機器學習:識別人臉,並在臉頰上畫草莓

☞瑞幸咖啡自曝虛假交易 22 億,App 反衝 TOP 1

☞在Kubernetes上部署一個簡單的、類PaaS的平臺,原來這麼容易!

☞曠視提雙邊分支網絡BBN:攻堅長尾分佈的現實世界任務 | CVPR 2020 Oral

☞2020年,這20個大家都認識的加密交易所過得怎麼樣?


分享到:


相關文章: