newsence
來源篩選

Avoid Mini-frameworks | laike9m's blog

laike9m's blog

The author argues against creating internal mini-frameworks on top of existing tech stacks, as they often lead to increased complexity, maintenance burdens, and technical fragmentation. Instead of inventing new concepts that increase cognitive load, developers should focus on building libraries or linking abstractions directly to concrete business needs.

newsence

避免開發微型框架 | laike9m 的部落格

laike9m's blog
2 天前

AI 生成摘要

我認為應該避免在現有技術棧上開發微型框架,因為這類框架往往會增加複雜性、維護負擔並導致技術碎片化。與其發明增加認知負荷的新概念,我們應該優先開發函式庫,或確保抽象層能直接對應具體的業務需求。

避開迷你框架 (Mini-frameworks) | laike9m 的部落格

查看 Hacker News 上的討論

過去幾年我在 Google Ads 工作。隨著時間推移,我看到一種模式反覆出現,給開發者帶來無盡的痛苦,那就是:建立「迷你框架」(mini-frameworks)。

什麼是迷你框架?

首先,我想讓讀者了解我所謂的「迷你框架」是指什麼。想像一家擁有 1000 名工程師的公司,他們共享同一套技術棧。久而久之,某個團隊發現這套共享技術棧不盡如人意,可能是因為他們必須反覆編寫樣板代碼,或是性能不夠好,或其他原因。於是,他們決定在現有的技術棧之上建立自己的框架。當你聽到工程師在展示成果時,使用他們自創的概念和術語來實現他們的思維模型時,你就知道這是一個框架,而不僅僅是一個函式庫(library)。這類框架就是我所說的「迷你框架」,它們通常具有一些共同特徵:

如果你在大公司工作,很可能見過甚至親手做過這種事。但為什麼這很糟糕呢?作為受害者,我可以分享我的故事。

我的故事

多年來,我的團隊一直使用 Google 內部的框架來編寫服務端代碼,並逐漸將我們部門的代碼庫遷移到該框架上。這個框架設計精良,並由專門的團隊維護。我們總體上對它很滿意,雖然它有一些讓人心癢的小毛病(不是痛點)。作為一名強大且有野心的工程師,我的主管提議在該框架之上增加一個抽象層,目的是降低部門採用的門檻,並順便解決那些小毛病。我當時持懷疑態度,並試圖說服主管不要這樣做,但失敗了。最終,幾名工程師花了數個季度的時間增加了這個抽象層,接著好戲開場了。

首先,其中一位作者嘗試在我們現有的代碼庫中採用它。大家原以為這會很容易,結果卻花了大約一年的時間。為什麼?因為在遷移過程中,他們發現這個抽象層無法處理某些使用場景,所以不得不花時間打補丁使其運作。與此同時,像我這樣的其他人仍在用原始框架編寫新代碼,這又增加了遷移的新需求和工作量。最終,在花費了遠超預期的時間後,遷移完成了,我的主管決定新編寫的代碼必須使用我們自己的框架。

你以為這就結束了嗎?當然不是!

自從我開始用新框架寫代碼以來,沒有一次是不想咒罵並辭職的。這個框架非常難用,它為了隱藏複雜性而引入了過多概念,結果反而帶來了更多複雜性。因為我不是編寫它的人,我不熟悉所有的技巧和偏門方法。結果,以前我一天就能完成的工作,現在可能要花兩週,而且我還得不斷詢問作者某些事情該怎麼做,甚至預約了結對編程(pair-programming)。據我所知,其他團隊成員也有同樣的抱怨。至於最初推動採用的目標,當然沒有起到幫助(如果沒有讓進度變慢的話)。諷刺的是,這個抽象層本應讓團隊以外的人更容易寫代碼,但現在連我們自己的團隊都深受其害。

回過頭來看,部分問題是由於糟糕的設計和實現造成的,但根本問題在於最初建立迷你框架的這個決定。我觀察過其他的迷你框架,它們或多或少都有同樣的問題,只是嚴重程度不同。因此,我總結了幾點想法來解釋為什麼迷你框架很糟糕。

為什麼迷你框架很糟糕?

第一,迷你框架缺乏功能完整性和兼容性。人們常以為自己可以神奇地「隱藏不必要的複雜性」,但現實中往往做不到。即使迷你框架能處理 80% 的使用場景,它們通常也缺乏原始框架的靈活性和功能來滿足剩下的 20%。DSL(領域特定語言)也有同樣的問題,這也是為什麼人們如此討厭它。

第二,迷你框架違反了 ETC(易於修改,Easier To Change)原則。我最早是從傳奇著作《程序員修煉之道》(The Pragmatic Programmer)中學到這個概念的,令我驚訝的是,許多程序員(甚至是資深程序員)竟然沒有意識到這一點。簡單來說,它建議編寫代碼時應考慮到未來的修改能輕鬆進行。建立迷你框架在兩方面違反了這一原則:

第三,迷你框架是創作者思維模型的體現,但並非每個人的思維模型。傾向於建立迷你框架的人通常更有主見,這本身是件好事。但當你為他人創造工具時,過於主觀會產生問題。我甚至會說,有時(並非總是)建立迷你框架直接反映了作者的虛榮心,他們選擇框架是因為一個小小的函式庫無法體現「這項工作的重要性」。

第四,迷你框架往往會導致技術棧碎片化。我生成了一張圖來說明我的意思:系統的一部分已遷移,另一部分則沒有。隨著新層不斷增加,情況會隨時間惡化。不確定其他公司是否如此,但在 Google,我從未真正見過一個代碼遷移能完全完成,這有點滑稽。

圖片

最後也是最令人擔憂的一點:缺乏維護。與由專門團隊擁有的共享基礎設施不同,迷你框架通常由創建它的那一兩個人擁有。一旦他們離開團隊或公司,就很難找到繼任者——當然其他團隊成員可能大致了解其運作方式,但肯定不如作者深入。此外,人們缺乏維護現有東西的動力,因為做這件事不會讓你獲得加薪或晉升。因此,迷你框架往往隨著原作者的離職而消亡,除非在那之前它已經獲得了大規模採用,而這種情況發生的機率微乎其微。

那麼,你應該怎麼做?

在這一點上,有必要澄清我反對什麼,不反對什麼。我當然不反對增加抽象——因為抽象本質上就是程序本身,我們離不開它。我反對的是以錯誤的方式增加抽象,以及增加不必要的抽象。

讓我再次強調這一點,因為它非常重要:
函式庫(library)和框架(framework)之間真正且唯一的區別,在於它是否引入了新概念。界限有時可能很模糊,但通常很容易辨別。例如,一個函式庫可以包含圍繞原始框架的一組子類或工具函數,因為它們沒有引入新概念。但如果你看到一個 README 以「術語表」(Glossary)章節開頭,那麼 99.99% 的機率它是一個框架(人們可能仍稱之為「函式庫」,但你懂我的意思)。

我的觀點是,我們在引入新概念時應該非常非常小心。如果可以,請避免這樣做。一堆流行詞彙帶來的認知負荷比人們意識到的要重,尤其是框架作者所能意識到的。文字是思想的鏡子,代碼亦然。作者創造概念是因為這是他們在大腦中對問題建模的方式,是他們的思考方式。這就是為什麼他們聲稱這些概念「自然且直觀」,而其他人卻在苦苦理解。

所以第一條規則是:避免建立迷你框架,改為建立函式庫。但在你確實發現有必要建立框架的情況下,我的建議是:

將概念與具體的業務需求掛鉤,而不是你腦袋裡的某種想法。

從零開始。不要圍繞現有框架構建包裝層(wrapper),而是從頭開始構建你自己的框架。是的,這將使它成為一個需要更多討論和資源的重大決策,但它能避免上述許多問題。畢竟,你有充分的業務理由這樣做,對吧……對吧?