架構設計:複用是邪惡的
在系統設計和寫代碼的過程中,我經常會聽到「複用」這個詞,以「複用」爲目的來設計技術,業務,組織架構。例如:
-
抽象出一個類,函數,UI 組件,用於不同的場景
-
抽象出一個微服務,越細越好,這樣可以靈活的組合
-
抽象出一個業務中臺,沉澱各種基礎業務功能,供全公司使用
-
組織(管理)架構中,抽象出一個職能豎井(後端,前端,QA,財務),被不同的產品使用
-
產品設計中要完成一個性能功能,發現跟之前一個功能相似,就複用之前的功能設計,改改繼續用
爲什麼我們喜歡複用呢?
-
主要目的:既然一部分功能已經存在,爲什麼還要自己造呢?直接拿來用,這樣我可以做得更少,所以能夠提升個人的生產效率。
-
接受的教育:一直以來的教育,大部分工程師都學習過 DRY principle;《設計模式》的的英文書名就是 《可複用面向對象軟件的基礎》,都在強調複用。
-
編程習慣:在面嚮對象語言裏,工程師習慣了繼承,而繼承對於大部分人來說的目的就是複用
認爲複用可以提高效率的推理邏輯是怎樣的?
-
如果我們要寫一個系統的所有代碼,我們需要寫大量的代碼。
-
如果我們能從其他地方重用一些以前寫過的代碼,我們就能寫更少的代碼。
-
我們能重用的代碼越多,我們寫的代碼就越少。
-
我們寫的代碼越少,我們就會越早完成系統!
這樣的推理邏輯是存在如下誤區:
-
所有的代碼(功能)需要相同的時間來寫
-
寫代碼是完成系統的最主要工作
如果你要寫得代碼依賴很多其他的「複用」模塊,你就要去理解不同的「複用」模塊提供的接口,很多時候只看文檔都不行;如果「複用模塊」的接口不是正好是適用你的場景,你就必須在講究使用接口和對方排期之間進行選擇。
此外對於如何抽象出一個公共業務模塊,大部分人都沒什麼標準,公共業務模塊的負責人成了業務的外包,效率更低。
另一點是任何維護生產環境系統的人都知道寫代碼只是整個工作中一小步,而且是確定性最高的一步,之後維護纔是最佔用時間的。我們需要不斷地進行調試,部署,再調試,部署。一個用於很多依賴的模塊相對依賴少的模塊做這些工作的難度是高很多的。
你說複用帶來了這麼多問題,那我們平時使用各種框架,基礎算法庫都要自己寫一份嗎?
肯定不需要自己再寫一份,我們平時會使用各種編程語言(Java,Go),框架,庫。我們使用這些沒有任何問題,因爲這是共識和標準,他們是足夠「通用,一般化」,並不是爲了某個業務或者某個公司定製的。先有「共識,標準」,再談複用,絕對不是隨意的拿過來用。
那我設計系統時,儘量將我的設計通用化就好了(例如拆很多個 CRUD 的微服務),這樣就能更多的進行復用,提高生產效率對嗎?
複用不是系統要追求的目標。很多人認爲更多模塊的「複用」,就可以做到像樂高一樣快速搭建系統,但是很多複用並不是樂高,而是器官移植,不僅不能提高效率,要不斷面對各種各樣的排異反應,降低了速度和穩定性。很多創業公司快速發展時系統腐化的主要問題就出現在了強行復用上。強行復用的案例很常見,例如:
-
上百個字段的數據表(例如訂單表,數據表),不清楚哪個字段在哪個場景下有效
-
根據名詞來設計系統,出現業務中臺,例如訂單中臺,電商中臺,各部門之間不斷地扯皮
-
出來無數個小的微服務,然後搞個統一的業務編排調度層(所謂的 gateaway)來處理業務,可能還抽象 DSL;上線十分複雜,需要發佈 N 各模塊;調度模塊是系統大單點,穩定性迭代速度都是問題
如果有一個好的設計,我們需要謹記《Hints for Computer System Design》中的「Use a good idea again instead of generalizing it. A specialized implementation of the idea may be much more effective than a general one.」
那系統設計好的標準是什麼?衡量的維度有優先級嗎?
兩個評價標準自治性和一致性:
-
自治性:受其他模塊的影響程度,觀測模塊的接口是否穩定。可以使用 AutonomyMetrics[1] 進行衡量
-
一致性:應該使用一個模塊的地方使用一個模塊的程度,也可以衡量是否過早,過度抽象了。可以使用 ConsistencyMetrics[2]
在業務層次是否要從多個業務模塊中抽象出一個底層模塊,可以通過多個業務模塊的這部分公共邏輯部分是否要一起進行改變進行判斷,如果不是需要一起變化的就不要抽象出公共模塊。
根據個人經驗如果你在要從各個業務模塊進行抽象出一個模塊保持一致與保持在模塊保持自治之間猶豫時,要毫不猶豫優先選擇「自治」。
總結
大部分情況下系統的核心複雜度不會減少, 只是轉移;不會因爲所有代碼一個人寫,會比分成兩個人寫更快,分工是應該且必須的。但是請注意的是:
-
不要爲了複用隨意通用化,抽象化,複用不是目的。如果要通用化就拿 ConsistencyMetrics[2] 來判斷是否是抽象合理的。
-
不要隨意複用其他的模塊,自治優先,用 AutonomyMetrics[1] 衡量;如果要複用一定要確保共識和標準優先,形不成共識和標準就不用複用。
相關鏈接:
-
https://autonomy.design/Part1/AutonomyMetrics.html
-
https://autonomy.design/Part1/ConsistencyMetrics.html
參考鏈接:
-
https://zhuanlan.zhihu.com/p/356202989
-
https://udidahan.com/2009/06/07/the-fallacy-of-reuse/
-
https://zhuanlan.zhihu.com/p/138145081
-
https://zhuanlan.zhihu.com/p/410049005
本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源:https://mp.weixin.qq.com/s/Gwt0neBHtSjHPK4bJJjeeA