可犧牲的架構

jopen 10年前發布 | 21K 次閱讀 架構

        英文原文:SacrificialArchitecture

        你坐在會議室里,凝視著你的團隊在過去數年一直維護的代碼。你已經做出了決定,你現在能夠做的、最好的選擇就是扔掉所有的代碼,重建一個全新的架構。對于這些命中注定的代碼、你投入其中的時間、此刻之前所做的那些決定,你該作何感想呢?

        對于很多人而言,扔掉代碼庫是失敗的象征,鑒于軟件開發固有的探索性質而言是可理解的,但是,這仍然是失敗。

        不過,你現在能夠編寫的最好代碼常常是你在數年之后要拋棄的代碼。

可犧牲的架構

        我們經常把偉大的代碼視作永久的軟件。作為一名編輯,我寫這篇文章時的身份可追溯到 1980 年。對于軟件架構是如何減輕某種永久做了很多思考。然而你的成功可以建立在代碼之上,因為被送到了 /dev/null。

        想一下網絡上最成功的大型商務網站之一的、eBay 的故事。它在 1995 年用了一周時間,從一堆 perl 腳本開始。在 1997 年,它推翻一切,在當時的 windows 工具之上,用 C++ 編寫的系統取而代之。然后到了 2002 年,應用程序用 Java 重寫了。早期的版本因為它們被取代了就成為了錯誤嗎?很難這樣說。eBay 目前仍然是 web 上最偉大的一個成功,但是成功的大部分因素是建立在 90 年代被拋棄的那些軟件上。就像很多成功的網站一樣,eBay 已經看到了指數級的增長,指數級的增長對于架構不是友好的。支持 1996 年 eBay 的合適架構,對于 2006 年 eBay 來說,就不是合適的了。1996 年的架構無法處理 2006 年的負載,但是 2006 年的版本太過復雜而難以建立、維護,它是根據 1996 年的需求演化而來的。

        的確,這個原則可以引出工作的一種組織方式。在 Google,大家熟知的要求就是設計一個滿足當前 10 倍需求的系統,這暗示著如果需求超過了一個數量級,那么扔掉并從頭做起是更好的。每隔幾年就被重新設計與拋棄的子系統而言,這是非常普遍的。

        的確,我們通常可以看到,剛接手一個成熟代碼庫的人們詬病架構的性能和可伸縮性。但是在軟件系統的早期階段,你不一定要確保它真正需要做什么, 關注靈活性以應付功能改變是十分重要的,而不是性能或可獲得性。隨著你的用戶越來越多,你需要切換優先級了,不過讓太多用戶處在一個低性能的代碼庫,通常 是優先級較高的問題,而不是優先級低。Jeff Atwood 發明了一句話“性能是功能”,一些人把它理解成性能總是第一優先級。但是任何功能只是你不得不從其它功能選出的。這不是說,你應該忽視性能之類的工作—— 軟件可以變慢、不可靠到斷送一個業務——但是團隊不得不與其它需求做出痛苦的抉擇。通常有更多的業務決定,而不是技術上的決定。

        那么這意味著要故意選擇一個可犧牲的架構嗎?本質上它意味著接受,因為若干年后你將(如果順利的話)扔掉當前創建的東東。這說明了要接受你堆放 在一起的、跨功能需求的限制。這也說明了現在需要考慮,當這一刻到來的時候,如何能夠讓其變得容易——軟件設計師很少考慮如何設計他們的創造,以支持將來 的優雅替換。這也意味著在相對短的時間內被扔掉的軟件,仍然帶來了很大的價值。

        明白了你的架構是可犧牲的,不代表要放棄軟件的內部質量。通常,被犧牲掉的內部質量,將比替代時間更早地傷害到你,除非你已經工作在行將退役的 代碼庫上。良好的模塊化是健康代碼庫的關鍵部分,模塊化通常在替換系統時起到巨大的幫助。對于系統的早期版本,要做的最好的一項工作就是搞清楚什么是最好 的模塊化結構,為將來的替換做準備。雖說在早期犧牲一整個系統是合理的,但是如果具備良好的邊界,隨著系統的增長,犧牲單個模塊是更有效率的。

        處理這個問題時,容易忽略的一個方面就是結算。是的,真的如此——我們已經陷入人們不情愿替代一個明顯的、不可行的系統的狀況,因為他們正在分期償還代碼庫的方式。對于大企業,這更像是一個問題,但是不要忘了,只要你生活在這個世界上,就要去檢查一下。

        你還可以把這個原則應用到現有系統的功能上。如果你正在開發新功能,那么只讓一部分用戶可見是明智的,因為你能夠得到它是不是一個好想法的反 饋。為了達到這個目的,開始的時候,你可能在以一種可犧牲的方式在開發,你不必在一個功能上投入全力,因為你可能發現它不值得全面部署。

        模塊可替換性對于微服務是一個主要論據,但是我謹慎推薦可犧牲的架構。微服務暗示著分布和同步,它倆都是復雜的助推器。我已經碰到過一些項目, 它們在走不是真正需要的微服務道路——結果嚴重減緩了它們的功能管道。因此,借助后來引入的微服務,逐漸將龐然大物分解,而龐然大物經常是好的可犧牲架 構。

        編寫可犧牲架構的團隊要決定犧牲它的時機。對于接手的新團隊而言,他們討厭現有代碼、想重寫,這是不同的情況。如果你沒有理解已編寫代碼的上下文,你很容易就厭惡你沒有編寫的代碼,明白你將要編寫的代碼屬于可犧牲的代碼,將是一個有用的變數。

        致謝

        與 Randy Shoup 的談話啟發了我,并幫助我構思了本文,尤其是 eBay(和一些 Google 的類似故事)的歷史描述。 Jonny Leroy 指出了結算問題。Keif Morris, Jason Yip, Mahendra Kariya, Jessica Kerr, Rahul Jain, Andrew Kiellor, Fabio Pereira, Pramod Sadalage, Jen Smith, Charles Haynes, Scott Robinson and Paul Hammant 提供了有幫助的評論。

                    <span id="shareA4" class="fl">                             
                        </span>
 本文由用戶 jopen 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!