《高效程式設計師的45個習慣》簡評及書摘

veldts發表於2011-12-17

Practices of an Agile Developer

—— Venkat Subramaniam,Andy Hunt

一句話,這本書算是程式設計師的心靈雞湯。書中所寫所引,不少箴言/警言,收穫多少,存乎一心。

本書許多條目其實與敏捷無關,但為了吸引眼球,讓內容敏捷,紛紛在前頭加上“敏捷”二字。《高效程式設計師的45個習慣》似乎是在向《程式設計師修煉之道》致敬,前者45條,後者46條,但看下來,前者遠不如後者精緻。整本書讀下來,個人覺得此書主筆只有Venkat,封面上的Andy貌似只是打醬油,為自家出版的書充一下門面。


1. 做事

如果你說的話只是讓事態更復雜,或者只是一味地抱怨,或者傷害了他人的感情,那麼你無意中在給問題火上澆油。相反,你應該另闢蹊徑,問問“為了解決或緩解這個問題,我能夠做些什麼?“在敏捷的團隊中,大家的重點是做事。你應該把重點放到解決問題上,而不是在指責犯錯者上面糾纏。

Blame doesn't fix bugs 指責不會修復bug

把矛頭對準問題的解決辦法,而不是人。

勇於承認自己不知道答案,這會讓人感覺放心。一個重大的錯誤應該被當作是一次學習而不是指責他人的機會。團隊成員在一起工作,應該互相幫助而不是相互指責。

如果你沒有犯過任何錯誤,就說明你可能沒有努力去工作。

如果一個團隊成員誤解了一個需求、一個API呼叫,或者最近一次會議做的決策,那麼,也許就意味著團隊的其他成員也有相同的誤解。要確保整個團隊儘快消除誤解。

如果大部分團隊成員(特別是開發領導者)的行為都不職業,並且他們對團隊目標不感興趣,你就應該主動從這個團隊中離開,尋找更適合自己發展的團隊(這是一個有遠見的想法,沒必要眼睜睜地看著自己陷入一個“死亡之旅“的專案中)。

2. 欲速則不達

Beware of land mines 防微杜漸

在工作壓力之下,不去深入瞭解真正的問題以及可能的後果,就快速修改程式碼,這樣只是解決表面問題,最終會引發大問題。快速修復的誘惑,很容易令人把持不住,墜入其中。短期看,它似乎是有效的。但從長遠來看,它無異於穿越一片流沙,你也許僥倖走過了一半的路程(甚至更遠),一切似乎都很正常。但是轉眼間悲劇就發生了……

Don't code in isolation 不要孤立地編碼

孤立非常危險,不要讓開發人員完全孤立地編寫程式碼。如果團隊成員花些時間閱讀其他同事寫的程式碼,他們就能確保程式碼是可讀和可理解的,並且不會隨意加入這些“+1或-1“的程式碼。閱讀程式碼的頻率越高越好。實行程式碼複審,不僅有助於程式碼更好理解,而且是發現bug最有效的方法之一。

所有的大型系統都非常複雜,因此沒有一個人能完全明白所有的程式碼。除了深入瞭解你正在開發的那部分程式碼之外,你還需要從更高的層面來了解大部分程式碼的功能,這樣就可以理解系統各個功能塊之間是如何互動的。

3. 對事不對人

對一個明顯的錯誤有哪些常見的反應:

  • 否定個人能力。(那樣很蠢!) 無助於提高他的水平,反而會令他以後不再提出自己的任何想法。
  • 指出明顯的缺點,並否定其觀點。(那樣很蠢,你忘記考慮它要執行緒安全。) 至少觀點明確,但也不能給Lee太多幫助,甚至可能會讓自己惹火上身,畢竟智者千慮必有一失。
  • 詢問你的隊友,並提出你的顧慮。(謝謝,Lee先生。但是我想知道,如果兩個使用者同時登入會發生什麼情況?) 沒有指責,沒有評判,只是簡單地表達自己的觀點。讓Lee自身意識到這個問題,而不是掃他的面子,(通常這是個很好的技巧:用引導的方式地提出疑問,讓被問者自己意識到問題。)負面的評論和態度扼殺了創新。

我們每個人都會有好的想法,也會有不對的想法,團隊中的每個人都需要自由地表達觀點。即使你的建議不被全盤接受,也能對最終解決問題有所幫助。不要害怕受到批評。記住,任何一個專家都是從這開始的。用Les Brown的一句話說就是:“你不需要很出色才能起步,但是你必須起步才能變得很出色。“

You don’t have to be great to get started, but you have to get started to be great. - Les Brown

It is the mark of an educated mind to be able to entertain a thought without accepting it. - Aristotle

能容納自己並不接受的想法,表明你的頭腦足夠有學識。 - 亞里士多德

團隊決策的若干技術:

  • 設定最終期限 避免陷入無休止的理論爭辯。
  • 逆向思維 找出優點最多缺點最少的那個方案。
  • 設立仲裁人 確保每個人都有發言的機會,並維持會議的正常進行。防止明星員工操縱會議,並及時打斷假大空式發言。
  • 支援已經做出的決定 一旦方案確定,每個成員都必須通力合作,努力實現這個方案。

不帶個人情緒並不是要盲目地接受所有的觀點。用合適的言語和理由去解釋為什麼你不贊同這個觀點或方案,並提出明確的問題。

4. 排除萬難,奮勇前進

假如要你修復其他人編寫的程式碼,而程式碼很難理解也不好用。你是應該繼續修復工作,保留這些髒亂的程式碼呢,還是應該告訴你的老闆,這些程式碼太爛了,應該通通扔掉呢?

也許你會跳起來告訴周圍的人,那些程式碼是多麼糟糕,但那只是抱怨和發洩,並不能解決問題。相反,你應該重寫這些程式碼,並比較重寫前後的優缺點。動手證明(不要只是嚷嚷)最有效的方式,是把糟糕的程式碼放到一邊,立刻重寫。列出重寫的理由,有助於你的老闆(以及同事)認清當前形勢,幫助他們得到正確的解決方案。

5. 跟蹤變化

如何才能跟上技術變化的步伐呢?下面是一些建議:

  • 迭代和增量式的學習 每天計劃用一段時間來學習新技術,不需要很長時間,但需要經常進行。記下那些你想學習的東西——當你聽到一些不熟悉的術語或者短語時,簡要記錄下來,然後在計劃的時間裡加以深入研究。
  • 瞭解最新行情 選擇一些公認的優秀技術部落格,經常去讀一讀,以瞭解那些頂尖的部落格作者都在關注什麼。
  • 參加本地的使用者組活動 積極參與問答環節
  • 參加研討會 許多知名的顧問或作者主持的研討會或課程。
  • 如飢似渴地閱讀 一些關於軟體開發和非技術主題的好書,專業期刊和商業雜誌,甚至是一些大眾媒體新聞

跟蹤技術變化。你不需要精通所有技術,但需要清楚知道行業的動向,從而規劃你的專案和職業生涯。

6. 對團隊投資

每週,要求團隊中的一個人主持講座,給大家介紹一些概念,演示工具,或者做些團隊感興趣的事情。也可以挑一本書,給大家說說其中一些特別的內容、專案或者實踐。無論什麼主題都可以。從每週主持講座的人開始,先讓他講15分鐘,然後進行開放式討論,這樣每個人都可以發表自己的意見,討論這個主題對於專案的意義。

堅持有計劃有規律地舉行講座,持續、小步前進為上,稀疏、間隔時間長的馬拉松式會議不可取。

享有盛名的爵士吉他手Pat Methany說過這樣一句話:“總是要成為你所在的那個樂隊中最差的樂手。如果你是樂隊中最好的樂手,就需要重新選擇樂隊了。我認為做其他事情也是同樣道理。“

7. 懂得丟棄

學習一門新技術時,多問問自己,是否把太多舊的態度和方法用在了新技術上。學習物件導向程式設計和學習程式導向程式設計是截然不同的。很容易發現有人用C語言的方式編寫Java程式碼,用VB的方式編寫C#程式碼。這樣,你辛辛苦苦轉向一門新的語言,卻得不到期望獲得的好處。

沉舟側畔千帆過,病樹前頭萬木春。要果斷打破窠臼,一味因循守舊會危害你的職業生涯。

對於所使用的語言,要總結你所熟悉的語言特性,並且比較這些特性在新語言或新版本中有什麼不同。

24. 傾聽使用者的聲音

每一次抱怨的背後都隱藏了一個事實。找出真相,修復真正的問題。

25. 程式碼要清晰地表達意圖

Hoare on Software Design

by C.A.R. Hoare

There are two ways of creating a software design. One way is to make it so simple that there are obviously no deficiencies. And the other way is to make it so complicated that there are no obvious deficiencies.

軟體設計有兩種方式。一種是把軟體設計得儘量簡單,並且明顯找不到缺陷;另一種是設計得儘量複雜,並且找不到明顯的缺陷。

開發程式碼時,應該更注重可讀性,而不是隻圖自己方便。程式碼閱讀的次數要遠遠超過編寫的次數,所以在編寫的時候值得花點功夫讓它讀起來更加簡單。實際上,從衡量標準上來看,程式碼清晰程度的優先順序應該排在執行效率之前。

26. 用程式碼溝通

用註釋溝通。使用精心挑選、含義明確的命名。用註釋描述程式碼意圖和約束。註釋不能替代優秀的程式碼。

解釋程式碼做了什麼的註釋用處不那麼大,相反,註釋要說明為什麼會這樣寫程式碼。

28. 增量式程式設計

在編譯和測試的空檔,停下來想一想,並暫時遠離程式碼細節,這是保證不會偏離正確方向的好辦法。

要休息的話,就要好好休息。休息時請遠離鍵盤。

29. 保持簡單

Andy曾經認識一個傢伙,他對設計模式非常著迷,想把它們全都用起來。有一次,要寫一個大概幾百行程式碼的程式。在別人發現之前,他已經成功地將GoF那本書中的17個模式,都運用到那可憐的程式中。

簡單並不意味著簡陋、業餘或是能力不足。恰恰相反,相比一個過於複雜、拙劣的解決方案,簡單的方案通常更難以獲得。

Simple is not simplistic 簡單不是簡陋

程式碼幾乎總是可以得到進一步精煉,但是到了某個點之後,再做改進就不會帶來任何實質好處。這時開發人員就該停下來,去做其他方面的工作了。

要將目標牢記在心:簡單、可讀性高的程式碼。強行讓程式碼變得優雅與過早優化類似,同樣會產生惡劣的影響。

30. 編寫內聚的程式碼

Charles Hess先生1866年申請的專利,“可變換的鋼琴、睡椅和五斗櫃“。

33. 記錄問題解決日誌

維護一個日誌,儲存遇到過的問題以及對應解決方案,可以選擇符合需求的任何格式,比如:

  • 問題發生日期
  • 問題簡述(硬體平臺、裝置型號、應用版本、核心版本)
  • 解決方案詳細描述
  • 參考文章或網址,以提供更多細節或相關資訊
  • 程式碼片段、設定或對話方塊截圖,只要它們是解決方案的一部分,或者有助於更深入地理解相關細節

日誌應儲存為計算機可搜尋的格式,以便用關鍵字搜尋並快速定位。如果遇到的問題在日誌中找不到解決方案,在問題解決之後,記得馬上將相關細節記錄到日誌中去。

日誌應與他人共享,而不僅僅是靠個人維護。把它放到共享的網路驅動器中,以供其他人使用。或者建立一個Wiki,並鼓勵其他開發人員使用和更新其內容。

要記錄團隊做出一個重要決策的原因。否則,在6~9個月之後,想重新回顧決策過程時,相關細節可能很難記起來,很容易出現扯皮現象。

34. 警告就是錯誤

將警告視為錯誤。簽入帶有警告的程式碼,就跟簽入有錯誤或者未通過測試的程式碼一樣,都是極差的做法。簽入構建工具中的程式碼不應該產生任何警告資訊。

35. 對問題各個擊破

識別複雜問題的第一步,是將它們分離出來。既然不可能在半空中試圖修復飛機引擎,為什麼還要試圖在整個應用中,診斷其中某個組成部分的複雜問題呢?當引擎從飛機中取出來,而且放在工作臺上之後,就更容易修復了。同理,如果可以隔離出發生問題的模組,也更容易修復發生問題的程式碼。

Prototype to isolate 用原型進行分離

在模組化不足,分離特別困難時,最好花一些時間把關注的程式碼提取出來,而且建立一個可讓其工作的測試環境。

對問題各個擊破,這樣做有很多好處:通過將問題與應用其他部分隔離開,可以將關注點直接放在與問題相關的議題上;可以通過多種改變,來接近問題發生的核心——你不可能針對正在執行的系統來這樣做。可以更快地發現問題的根源所在,因為只與所需最小數量的相關程式碼發生關係。

以二分查詢的方式來定位問題是很有用的。也就是說,將問題空間分為兩半,看看哪一半包含問題。再將包含問題的一半進行二分,並不斷重複這個過程。

在著手處理問題之前,先查詢你的問題解決日誌。

38. 定期安排會面時間

坐著開的會議通常會持續更久,大部分人不喜歡站著進行長時間的談話。

要保證會議議題不發散,每個人都應該只回答下列三個問題:

  • 昨天有什麼收穫?
  • 今天計劃做什麼?
  • 目前有哪些障礙?

通常,立會都是在每個工作日的早些時候,且大家都在上班時舉行。但是不要把它安排為上班後的第一件事。要讓大家有機會從剛才混亂的交通狀況中恢復狀態,喝點咖啡,刪除垃圾郵件什麼的。一般來說,在大家到公司之後的半小時到一小時之內舉行,是個不錯的選擇。

每日立會有諸多好處。

  • 讓大家儘快投入到一天的工作中來。
  • 如果某個開發人員在某一點上有問題,他可以藉機將問題公開,積極尋求幫助。
  • 幫助團隊帶頭人或管理層哪些部分需要更多協助,並重新分配人手。
  • 讓團隊成員知道專案其他部分的進展情況。
  • 幫助團隊識別是否在某些東西上有重複勞動而耗費了精力,或者是不是某個問題已有現成的解決方案。
  • 通過促進程式碼和思路的共享加快開發速度。
  • 鼓勵向前的動力:看到別人報告的進度都在前進,會激勵彼此。

40. 實行程式碼集體所有制

要強調程式碼的集體所有制。讓開發人員輪換完成系統不同領域中不同模組的不同任務。

任何人都可能遭遇到諸如車禍等突發事故,或者有可能被競爭對手挖角。如果不向整個團隊分享知識,反而增加了喪失知識的風險。

41. 成為指導者

Knowledge grows when given 教學相長

好的想法不會因為被許多人瞭解而消弱。當我聽到你的主意時,我得到了知識,你的主意也還是很棒。同樣道理,如果你用你的蠟燭點燃了我的,我在得到光明的同時,也沒有讓你的周圍變暗。好主意就像火,可以引領這個世界,同時不削弱自己。 - 托馬斯·傑斐遜

通過詳細解釋自己知道的東西,可以使自己的理解更深入。當別人提出問題時,也可以發現不同的角度。也許可以發現一些新技巧——聽到一個聲音這樣告訴自己:“我以前還沒這麼思考過這個問題。“

多數時候,成為指導者,是指在幫助團隊成員提升水平的同時也提高自己。

成為指導者意味著要分享——而不是固守——自己的知識、經驗和體會,要對別人的所學和工作感興趣,同時願意為團隊增加價值。一切都是為了提高隊友和你的能力與水平,而不是為了毀掉團隊。

42. 允許大家自己想辦法

授人以魚,莫若授人以漁。

不要直接給出答案,而應給於指引,這麼做有如下好處:

  • 你在幫助他們學會如何解決問題。
  • 他們可以學到答案之外的更多東西。
  • 他們不會再反覆問你類似的問題。
  • 這樣做有助於他們在你無法回答問題時自己想辦法。
  • 他們可能會想出你沒有考慮到的解決辦法或者主意。這是最有意思的,你也可以學到新東西。

用問題來回答問題,可以引導提問的人走上正確的道路。

如果有人真的陷入膠著狀態,就不要折磨他們了。告訴他們答案,再解釋為什麼是這樣。

44. 程式碼複查

最基本的檢查單:

  • 程式碼能否讀懂和理解?
  • 是否存在明顯的錯誤?
  • 程式碼是否會對應用其他部分產生不良影響?
  • 是否存在重複的程式碼(在複查的這部分程式碼中,或是在系統的其他部分程式碼)?
  • 是否存在可以改進或重構的部分?

相關文章