最近讀完了《軟體設計哲學》,第二章探討了軟體複雜性的議題。
《軟體設計哲學》一書實際定義了複雜性:
「複雜性是指與軟體系統的結構相關的任何使其難以理解和修改的事物。」
換句話說,複雜性可以有多種形式,並且不一定與效能有任何關係,您的程式碼可以具有高效能但仍然很複雜
我想在本文中分享本書中的一些關鍵定義和見解。但首先,讓我們想像一個您可能已經經歷過的常見情況...
讓我們深入探討許多人可能已經經歷過或將要經歷的恐怖故事。
它始於一個簡單的 CRUD 任務管理應用程式。程式碼乾淨、模組化且易於維護。開發團隊很高興,系統對於最初的客戶來說運作得很好。
當銷售團隊將系統出售給一家大公司時,問題就開始了,聲稱它具有日曆整合、電子郵件通知和令人驚嘆的報告產生器。銷售完成後,這些功能必須快速實施。
日曆整合:團隊必須與 Google 日曆和 Outlook 整合。不同的開發人員實施了解決方案,導致方法不一致。
電子郵件通知:接下來新增了電子郵件通知。一位開發人員使用特定的庫,而另一位開發人員創建了自訂解決方案。混合的方法使程式碼變得混亂。
報告產生器: 對於報告產生器,開發人員使用了各種技術:PDF、Excel 匯出和互動式儀表板。缺乏統一的方法使維護成為一場噩夢。
複雜性不斷增加:每個功能都是獨立快速開發的,導致功能之間存在依賴關係。開發人員開始創建「快速修復」以使一切正常運行,從而增加了系統的複雜性和耦合性。
軟體開發不是在真空中進行的;而是在現實中進行的。各種內部和外部因素都會對其產生影響。我們都曾經或將會經歷過這樣的情況。
然後問題就開始了:
很明顯,我們現在擁有一個複雜的系統。
現在讓我們「剖析」這種複雜性,以便更容易識別和緩解它。
嗯,「緩解」的意思是:
「減輕嚴重性、嚴重性或痛苦;緩解。」
我相信複雜性通常是程式碼所固有的。有些事情本質上是複雜的。作為開發人員,您的角色不僅僅是創建電腦可以有效執行的程式碼,還要創建未來的開發人員(包括未來的您)可以使用的程式碼。
「控制複雜性是電腦程式設計的本質。」
— 布萊恩·科尼漢
上述書籍的作者指出,複雜性通常以三種方式表現出來,我們將在這裡進行探討。
當看似簡單的更改需要在許多不同的地方進行修改時,就會發生更改放大。
例如,如果產品負責人要求「優先順序」或「完成日期」字段,並且您的實體緊密耦合,那麼您需要進行多少更改?
認知負荷是指開發者完成任務所需的知識量和時間。
想像一下這樣的場景:一位新開發人員加入了團隊,他被指派去修復報告產生器中的錯誤。為了完成此任務,開發人員需要:
這是典型的「無法估計」場景,任務可能需要 1 分或 8 分——最好擲 D20 並做出相應的反應。
未知的未知是指你不知道自己不知道的事。
這是複雜性最糟糕的表現,因為你可能會改變不應該改變的東西,導致一切崩潰。
範例:開發人員修改了電子郵件發送程式碼以新增通知,但沒有意識到這會影響依賴該函數的報告產生器。這給客戶帶來了重大問題,體現了緊急複雜性的最壞形式。
看完恐怖故事和三個主要症狀,讓我們看看是什麼導致了複雜性。
依賴關係在軟體中是必不可少的,並且無法完全消除。它們允許系統的不同部分相互作用並一起運行。然而,如果管理不當,依賴關係會顯著增加複雜性。
當程式碼無法單獨理解或修改時,就存在依賴關係,需要考慮或修改相關程式碼。
當重要資訊不明顯時,就會出現模糊性。這可能會使程式碼庫難以理解,從而導致認知負荷增加和未知未知的風險。
當重要資訊不明顯時,就會出現模糊。
因為它是增量的,所以很容易想到,「就這一次,沒關係。」但累積起來後,僅修復一兩個依賴項並不會產生太大影響。
「軟體工程中的一切都是權衡。」
— 我不記得作者了
我可以寫很多你可能已經在網路上看到的關於如何避免複雜性的規則、策略和框架:SOLID、設計模式、YAGNI、KISS 等。
但是,您可以將它們全部統一為一個指導原則(如“務實的程式設計師”中提到的。):「我正在實現的內容容易更改嗎?」如果答案是否定的,那麼您可能正在增加複雜性。
確保程式碼易於更改可以簡化維護,減少開發人員的認知負擔,並使系統更具適應性且不易出錯。
謝謝!
以上是與軟體複雜性的永無止境的鬥爭的詳細內容。更多資訊請關注PHP中文網其他相關文章!