此文章來自 The Effective Engineer 作者 Edmond Lau 的部落格。 Soft & Share 獲作者授權翻譯。

“我們只需要幾個小時來實現該功能,”我們有時這麼說。 但是在完成之後,我們發現每隔幾個星期,我們就要修復這個功能的錯誤,向另一個工程師解釋,或者幫助客服部門回答這些功能怎麼運作的問題。維護該功能的總投資時間遠遠超過了最初預估的幾個小時開發時間。

在軟體工程中內化最困難的課程之一是額外複雜性的隱藏成本。有時,複雜性只是問題範圍中固有的。匹配乘客和司機,同時調整價格以平衡供需是一個複雜而且困難的問題。因此,當要擴大使用者社群並且保持品質要將問題和回答分配給最可能回答和讀的懂的人 。 或者開發支援多平台的文件編輯器,可在所有設備上正常運作 ,並支持即時的協同作業(譯註 : 或是可利用現成的 Google Document )。 如此可幫助我們駕馭產品本質的複雜性以達到成功。

但是其它時候,我們搏鬥的複雜性是我們自己添加的。我們採用一種新的程式語言編寫,但這語言很少人知道,現在我們必須維護它。或者我們添加了額外的基礎建設,因為我們想嘗試在Hacker News上看到的最新熱門技術,但結果卻不如我們的預期最後失敗了。 或者我們引入了一個很少人使用的功能,但卻需要花很多不成比例的時間做問題回報和修復。

額外的複雜性帶來許多隱藏的成本。我們在建構軟體時所做的決策不僅決定著我們當前的開發速度,也對於我們以後要花費多少時間和精力來維護與繼續發展產生了影響。

複雜性的隱藏成本


太多的複雜性增加了認知的間接成本,並在完成任務的過程增加額外的摩擦。它對於一個團隊以多種不同的方式滲透 – 最直接透過程式碼、系統和產品的複雜性,但間接透過組織的複雜性。讓我們一個個來看這些不同類型的複雜性的隱藏成本。

程式碼複雜性

程式碼的複雜性不僅僅是依照程式碼行數做線性的增長 – 它是組合性地增長。在複雜的程式碼基底,每行程式碼可能與許多其它行程式碼交互作用並影響其它程式碼。我們的頭腦很難總結算出組合增長的效應,這就是為什麼我們常常大大地低估完成大型軟體專案所需的時間。這是為什麼重寫專案有時跟原本的時程安排差那麼多

當程式碼太複雜時,它變得越來越難,且也越難做推理,更難以解決問題。解開相依關係和資料流以追溯錯誤的來源變得很困難。工程師可能主動避免程式基底中最複雜的部分,而選擇繞過用別的方法解決即使它是最合理需要做修改的地方。或者他/她們可能同時避免在這些部分修改,即使這工作將產生高度的影響力。

系統複雜性

工程師總被新玩具吸引,也許是因為他/她們的好奇心,也或許是因為他/她們認為一項新技術可能會是解決他/她們迫切問題的銀色子彈。當 Pinterest 最初在2011年擴展其網站以應對快速成長時,他們在僅有3名工程師的後端團隊中使用了6種不同的儲存技術( MySQL、Cassandra、Membase、Memcache、Redis、MongoDB)。 (註1) 他們實驗的每種新技術在文件中都承諾解決他們既有系統的一些限制。但是,他們發現,每個新的解決方案卻以自己特殊的方式失敗,而且花掉他們更多的時間和精力來管理與維護。最終,團隊了解到,透過添加更多的機器而不是更多的技術將更容易擴展,因此他們拿掉了Cassandra和MongoDB等系統,並加強了其架構的其餘組件。

將基礎設施分割成太多系統帶來了許多隱藏成本。注意力被分散到多個系統。將每個系統的資源集合在一起建構可重複使用的程式庫(libraries)變得更加困難,更難以訓練新人讓他/她們能應付隨時待命的緊急需求,並且更難理解每個系統的特定故障模式與性能特徵。每個系統的抽象層(abstractions)最終都會變弱,因為無法對每個系統投入夠多的時間。當工具和抽象層(abstractions)太複雜或太多,它們會變得難以讓團隊理解和發現。

產品複雜性

產品複雜性可能源自於一個定義不清楚的願景或過度旺盛的野心導致缺乏聚焦的產品。這種想在許多方面都戰功彪炳而不是僅僅在一個核心領域有所表現反而凸顯了其無法向新的使用者簡明解釋產品的目的。產品複雜性導致更多的程式碼和系統的複雜性 – 團隊添加更多程式碼和更多基礎建設來支援新功能。當產品具有寬廣的面向,這也意味著添加新的功能或修改既有的功能需要很大的努力付出來理解並與舊的功能相容。

過於複雜的產品也代表著有更多的程式碼分支、更多的問題需要考慮、更多的 bug 回報需要團隊解決,工程師和資料科學家需要分析更多的變數、做更多的一次性報告,而不是專注於理解核心使用者行為。工程師需要投入更多的時間來提高對於功能區域的了解以達到生產力。每個人將會在更多專案之間疲於做不同的情境轉換。 當時間花在維護這些功能,就沒有時間投資在程式碼改善,如償還技術債務或強化抽象層(abstractions)。

組織複雜性

程式碼、系統和產品複雜性反過來增加了組織的複雜性。團隊需要雇用更多的人來處理和維護已經建構的一切。較大的團隊意味著更多的溝通成本,更多需要協調而且將會減損整體效率。招聘過程本身,包括所有面試和匯報,可以消耗團隊大部份的時間。當然,所有的新員工都必須接受到職教育訓練 (譯註 : 這也將花費既有的員工許多時間)。

僱用更多的人方法選擇之外,可將工程組織分成更小的團隊 – 甚至創立一人團隊。這降低了溝通成本,但是單人團隊也有自己的成本。它更容易遇到障礙,完全阻擋了一個專案中僅有的一人的前進。並且因為很少的人在共同的管道分享,這種獨自作戰的經驗更加不利於士氣,加上與其他人合作的機會較少,也可能傷害工作場所的幸福感和員工持續在此工作的慾望。除非每個人都有意識地和主動地要求反饋,否則個人工作因為共享相同專案背景的人較少,可能收到更少的反饋。減少的反饋可能導致較低品質的程式碼或無意間把複雜性帶入程式基底或基礎建設中。

如何對抗複雜性


Tony Hoare 在他的1980年圖靈獎(Turing Award l)講座中建議:“有兩種方法來建構軟體設計:一種方法是讓它非常簡單,沒有任何明顯的缺陷,另一種方法是讓它變得非常複雜,看不出明顯的缺陷“。在討論了由於複雜性導致的不明顯缺陷將如何傷害我們之後,我們要如何去防範這些成本?

以下是你可以使用的一些策略:

  • 為了簡單做最佳化。抵制增加更多複雜性的衝動。原因是維護的成本。問問自己,為了解決問題最後的20%所帶來的複雜性是否值得,或者80%的解決方案就足夠了。
  • 為你的團隊或產品定義任務說明以聚焦。在 Team Geek,Brian W. Fitzpatrick和Ben Collins-Sussman解釋了他們如何指導 Google Web Toolkit(GWT)團隊,並鼓勵他們寫下使命宣言。接下來關於任務說明的內容與風格的辯論顯示,領導工程師實際上並未就產品方向達成一致意見!他們被迫面對與調和他們的分歧,最終得出結論:" GWT 的使命是透過使開發人員能夠使用既有的Java工具為任何現代瀏覽器建構不折不扣的 AJAX,從根本上改進使用者的網路體驗。" 如果他們當初沒有早點從差異中錘煉出共識,你可以想像接下來有可能發生多少碎片性的努力?
  • 從較簡單的建構區塊組成大型系統。 Google 是一個組織的範例,致力於建構強大的核心抽象層(abstractions),然後廣泛運用於各種應用。它們具有基本的建構區塊,例如 Protocol Buffers、Google File System 和用於遠端程序呼叫的 Stubby 伺服器。在這些建構區塊之上,他們已經建構了其它抽象層,例如 MapReduce 和 BigTable 。在那些基礎上,建置數以千計的應用,包含大規模的網路索引、Google Analytics 網站跟踪、Google新聞分類、Google Earth 資料處理、Google Zeitgeist 資料分析等眾多應用。 (註2 註3)
  • 清楚地定義模組和服務之間的介面。去耦合( decoupling )模組和服務減少了組合的複雜性,因此可以產生一堆程式碼。在 Amazon,Jeff Bezos 在2002年宣布,公司將朝著服務導向的架構前進,所有團隊之間的通訊只能透過服務層級介面進行。(註4) 雖然單這套轉型就耗費了巨大的開發成本,但它強制將服務背後的程式碼與邏輯分開,並促進了現在非常成功的 Amazon Web Services 的創建。
  • 定期償還技術債。我們總是在不完整的資訊下建構軟體。隨著程式基底根據不斷變化的條件有機地生長,不穩定的熵也增加。增加的複雜性成為未來發展的稅。開發計劃中的預留償還技術債時間可以幫助降低成本。許多工程師和團隊在專案切換時預留時間,但是舉辦一次性活動也會有幫助。在Quora,我曾經組織過一個程式碼清除日,那天工程師專注於刪除程式基底中未使用的程式碼。我們做程式碼清除的進度排行榜,這使得這活動比純粹自己刪除程式碼更有趣。
  • 使用數據減少未使用的功能。在Yammer,當工程師或產品經理發現在程式碼重構中增強功能或保留功能需要花費不少的努力,他們會查看功能的使用數據,看看功能是否被真正使用。如果沒有,他們會與團隊決定是否應該削減功能,以減少整體工作。 (註5)這種策略類似以簡化程式碼減少技術債的方式來減少產品債。
  • 圍繞共同的議題組合進行中專案。這使得團隊成員能夠共享彼此相同的情境,這使得他/她們更容易參與設計討論,審查程式碼或是建構可以重複使用的程式庫(libraries)。所有這些活動將有助於提供個別工程師獨自工作時可能帶來問題的制衡。

當我們為學校的課程建構軟體時,我們採用了過於簡單的世界觀 – 維護任何複雜性的成本在課程結束時從沒出現過。但在我們的職業生涯中,錯誤的軟體開發決策將導致於未來幾年回頭跟你徵稅。

不要使事情複雜化。

文中註釋

原文網址  http://www.theeffectiveengineer.com/blog/hidden-costs-that-engineers-ignore

關於這篇文章作者

edmondlau-headshot-1-w400-54af35b37dcef5c8646f247dcd0e9ed570e6ea506a7a00d19c3e1880d3b1485f

 

Edmond 目前教導軟體工程師和技術經理如何有效率的建立有意義的影響力。

他是 Quip 早期的軟體工程師,曾經在 Quora、Google和 Ooyala 帶領軟體開發團隊。

著作:The Effective Engineer 

你可能會感興趣

  • The Effective Engineer – Team Package 團購 這是這篇文章作者Edmond根據他的工作經驗與訪談多位資深矽谷工程師所寫的一本書,Team Package 比單買電子書多了兩份作者整理的檢核文件( 其中一份文件就是在指引你如何一步一步增加你的影響力,你可以把這份文件當做是你的生涯規劃指南) 與他訪談的視訊,Team Package在作者網頁只開放給在同一家公司上班同事一起購買,Soft & Share特地與 Edmond 聯繫,取得了可以使用社群團購的方式購買Team Package。
  • Soft Skills 作者 John Sonmez 線上課程  軟體工程師應該如何自我行銷
  • Soft Skills 作者 John Sonmez 線上課程  不管學什麼都很快的十個步驟
  • Soft & Share 團購和特價線上課程  加入這個社團追蹤我們的團購訊息與 Udemy 特價課程
  • 追蹤這個   Twitter  ,得到 Udemy 特價課程訊息

 

喜歡我們的分享嗎?歡迎使用以下的社群分享按鈕分享給你的朋友吧!

發表迴響

在下方填入你的資料或按右方圖示以社群網站登入:

WordPress.com Logo

您的留言將使用 WordPress.com 帳號。 登出 / 變更 )

Twitter picture

您的留言將使用 Twitter 帳號。 登出 / 變更 )

Facebook照片

您的留言將使用 Facebook 帳號。 登出 / 變更 )

Google+ photo

您的留言將使用 Google+ 帳號。 登出 / 變更 )

連結到 %s

分類

03-Edmond Blog 翻譯, Engineering Best Practices