Facebook元老王淮眼中的軟體開發原則

infoq發表於2013-03-19

  王淮是Facebook的早期員工,也是Facebook內部第二位中國籍工程師和第一位研發經理,曾經負責支付後臺和安全系統,擔任反欺詐部門的技術經理。最近,他分享了一些基本的碼農原則,包括程式碼結構、測試重要性等。

  正確性是第一要求,他認為“不能解決問題的程式碼是耍流氓”。

  然後是程式碼結構,王淮覺得結構體現邏輯:

第一步,第二步,需要什麼資料,需要做什麼處理,處理完了結果到那裡去,都應該在結構中被很好的體現出來。

結構體現設計。 設計一定要清晰。我的經驗來看,一般來說,在設計結構圖上面的每個元件都對應著自己的類,然後之間或類內部的通訊通過成員函式來完成。

  他提供一個可借鑑的做法:在一個大的功能實現過程中,給出第一個diff(提交程式碼增量)的時候,可以只把結構當做一個diff,裡面的函式可以是空的(place holder,作為佔位符)。 把資料的生成和介面的展示分開來。典型的可以按照MVC的模式來,但也可以只把資料和UI介面分開來的比較輕量級的做法。結構應當是提交程式碼審查的時候最最關注的地方。最需要問的問題就是“這個diff號稱要解決的問題被正確解決了嗎?”

  測試的重要性不言而喻。王淮指出:

不論你再正確,還是有錯誤的時候。通過(相對)公正的測試一是來減少自己被繞到程式碼裡的機率,二是讓後續的或者別人的改動對自己程式碼不經意的破壞被最快的展現出來。測試應該把類主要的功能都測一遍。測試也應該把類和其他類最重要的整合部分也測一遍。

  對於提交程式碼增量的問題,王淮說了幾個需要注意的事項:

  • Bug修改,無所謂,該多大就多大。一般bug fix不會超過100行。超過的要特別重視,想想究竟是什麼原因造成。會不會是當初設計的問題。一個diff,原則上不應該超過200-300行修改。但多了怎麼辦,把一個diff變成多個。
  • 每個diff應該只做一件事情。每個diff儘可少的做一個改動。這樣可以儘可能的方便自己的管理(學會用git branch),和方便審閱者的程式碼審查。如果diff越集中做一件事,審查程式碼的人需要越短的時間來審查做出高質量的,整體效率越高。
  • 一個功能超過一屏,則將其分割。

  物件導向還是面向函式,王淮指出,Java本身就是物件導向,所以這個問題不大。但千萬不要出現披著物件導向的外皮,在類裡面寫超長的面向函式的處理。這種情況下,儘可能的分流成輔助函式。

  關於程式碼規範,他舉了一些簡單的例子:比如檔名,變數或函式名的命名規範,分行的前置空2個空格或4個;每行的字數(不應超過80字元);如何使用public/private/protected;用左右括號的原則;空行的使用;檔案和程式碼comments的位置 (比如,程式碼註釋只能單獨成行);對“// TODO:”的使用規範;巨集、常量的使用。這裡沒有特別的哪一種樣式一定更對,但是需要有一個大家統一的指南,一起遵守,讓整體的程式碼有統一的風格和標準。最大的好處就是有利於可讀性,可讀性的好壞決定著維護成本。

  註釋應當簡潔但充分。有些人覺得程式碼應該自說名。王淮不大同意,程式碼是實現細節,適當的在意圖上給予說明,可以大幅度的減少讀程式碼的人的煩惱。

  程式碼審查越來越受到重視,王淮指出:

  • 作為審查者,一定要讀懂diff;所有被接受的diff必須是在讀懂的前提下。做審查者的人要有“將來如果這些程式碼線上出問題,我要幫助支援”的心理準備。
  • 程式碼審查應該被每個工程師當做工作的重要一部分。
  • 應當在24小時內給回覆,這應當變成共識。
  • 感覺有問題的程式碼,一定要在相應的行上做出評論 (inline comments),以讓作者明白問題所在。
  • 儘可能把對修改的所有意見一次性給出,減少來來回回的次數。比較複雜的建議審查者主動找程式碼作者來進行線下溝通,達成一致。
  • 一般的diff,來回次數不宜超過3次;如果超過3次,想想看,是不是diff 太大,太複雜了。

  說到程式碼審查,thoughtbot公司最近在github上釋出了自己的程式碼審查原則,其中幾個值得關注的要點包括:

  • 接受這樣的現實:很多程式設計上的主張都是一種個人觀點。應該討論它們的利與弊,提出你的傾向觀點,迅速地達成一種解決方案。
  • 提問,而不是命令。(“把這個變數改成:user_id,你覺得如何?”)
  • 請求給予說明。(“我不明白。你能解釋一下嗎?”)
  • 避免程式碼的歸屬之爭。(“我的”,“不是我的”,“你的”)
  • 避免使用一些會被認為是有關人身特徵的詞語。(“笨蛋”,“愚蠢”)要把所有人都看作是有魅力的、聰明的、善意的。
  • 要明確。要記著並不是每個人都能理解你的意圖。
  • 要謙虛。(“我不能確定——我們來分析一下。”)
  • 不要用誇張修辭語。(“總是”,“從不”,“永遠”,“毫無…”)
  • 不要諷刺。
  • 展現真實的你。如果你不是幽默型的人,不喜歡使用一些表情符號或動畫gif圖,不要勉強。如果你是這種人,請自信的發揮。
  • 如果有太多的“我不理解”或“另一種方案:”的評論,請專門針對這個人進行交流。可以把你們線下的交流總結成一個帖子附在後面。
  • 對審查者的建議表示感激。(“謝謝提醒。我會把它改正。”)
  • 理解審查是對事不對人。審查的是你的程式碼,而不是你。
  • 解釋為什麼程式碼寫成這樣。(“因為xxx原因我才寫成這樣。如果我把這個類/檔案/方法/變數改個名會更清晰些嗎?”)
  • 整理所作的改動,在以後的迭代中重構它們。
  • 在做修改的版本上註明程式碼審查的連結。
  • push提交要基於最早的一輪反饋,並形成一個獨立的分支。等這個分支上的任務完全完成了再合併。這讓審查者能夠根據早先的反饋找到你的單獨的更新。
  • 努力站在審查者的立場上理解。
  • 爭取回復每個評論。
  • 直到最後一個人退出登入後再合併分支。
  • 直到持續整合測試(TDDium, TravisCI,等)告訴你這個分支的測試套件通過後再合併分支。

相關文章