軟體的複雜性
為什麼重要:軟體的複雜性會直接影響到公司的財務。
軟體複雜性會造成許多的影響:
- 人員流動率提高
- 生產力下降
- Defect density (Bug 數量/程式碼數量)提高
這些造成的影響都可以直接估算財務的損失,所以軟體的複雜性不會只影響到開發 Team,所有團隊都應該注意軟體複雜性的問題。
複雜性
什麼是複雜性:至少要經常考慮到的複雜性有 Problem Complexity(Inherited Complexity) 和 Solution Complexity(Accidental Complexity)。
需求是排序一筆資料這是 Problem Complexity;選擇排序的算法則是 Solution Complexity。
在複雜的問題上我們難以避免使用複雜的解法,但對於其他問題應該要避免複雜性超過問題本身,換句話說就是應該要以 Problem Complexity >= Solution Complexity 為目標。
有許多原因會意外造成 Solution Complexity 的增加(所以也稱 Accidental Complexity):
- 無意的:對剛加入的工程師不了解目前團隊的 Code Base,對已經現有的解決方案並不知情,或是在不同專案的架構不一樣、架構難以理解,都容易重新建立新的解決方法
- 目前的解決方法無法滿足需求
- 解決方法會增加依賴:例如其它的團隊、其它的 library 等
Problem Complexity 會因為 legacy code 多次搬動、重構或是經歷過需求多次的變更,隨著時間的演進變得更加的複雜,也因為已經產生了許多的依賴使得修改和新增非常的困難(所以也稱爲 Inherited Complexity)。
造成原因
系統複雜性的產生是因為許多因素造成的。
依賴性和模糊性是軟體複雜性的主要來源 - A Philosophy of Software Design
依賴性:當一段 Code 無法被獨立理解或是進行修改時,而必須將其他的部分一併的考慮進去。
模糊性:重要的資訊不夠明確,例如說明的不夠清楚或是缺乏相關的文件。
當系統複雜性提高時:
宏觀層面會感受到效率的低下、不穩定和不確定性的增加以及開發團隊的不滿和挫折。
微觀層面:
- Change amplification:微小的改動會同時需要更改許多的地方
- Cognitive load:開發者所需知識量的增加,例如需要更瞭解情況、系統的架構和原因,進而會影響到開發的時間
- Unknown unknowns:開發者未知的事情,例如評估時做時間時,未預料到有某些其它地方需要進行修改,或是更改後造成了其它意想不到的事情
複雜性源於狀態以及控制 - Out of the Tar Pit
系統在某一個狀態下的行爲無法推斷在其他狀態下的行為:
例如在購物車中有:
狀態 A:使用者有優惠券,商品有庫存
狀態 B:使用者無優惠券,商品無庫存
儘管我們完全理解了狀態 A 下的系統如何運作,我們仍然還是不知道狀態 B 會進行什麼流程。
控制,即順序也造成了系統的複雜性:
例如結帳流程以檢查庫存→計算運費→套用優惠→確認付款:
如果順序錯誤會導致可能先付款但是沒有庫存;先套用優惠後算運費總計金額也會不同。
如何解決
- 應該要注重架構長期的簡單性
- 減少意外的複雜性(過度複雜的框架、資料結構)
— Simple Made Easy
在選擇工具和語言時,要關注的不是易用性,而是透過他們建構的系統所帶來的複雜性。
Simple 是移除不必要的複雜性去專注真正需要的部分,但要注意 Simple 不等於 Eazy,簡單的解決方法不一定是容易實現的。
Entities should not be multiplied without necessity. - Occam’s razor
我們應該去選擇假設更少並更簡單的解決方式。
在開發中會有許多方案可以解決目前的情境,例如要迅速建立可以管理個人資料的網頁系統,有 2 種方案:
- 自行建立解決方案實現此功能,代表需要規劃 DB Schema、使用者身份驗證和創建管理資料的功能
- 利用現有的 OAuth 來實現需求,進行整合
在 Occam’s razor 理論中會優先採取方案 2 的做法,因為它的假設更少且要運作的部分也更少,雖然它不一定是最簡單的。
另外模組化也是一種常見的方式,要要特別注意的是這也會造成額外的複雜性產生,在抽象以及介面的實作都會產生複雜性。
陷阱
There is an essential complexity to all meaningful software.We can never eliminate that complexity; we can only control it.
Complexity has to live somewhere. If you embrace it, give it the place it deserves, design your system and organization knowing it exists, and focus on adapting, it might just become a strength.
專注於去除複雜性讓系統更簡單有時候會是個陷阱,有意義的軟體都有它的複雜性存在。
對於這些複雜性我們應該去透過包裝讓其他經驗較少的的人員可以簡單地去使用它。
Reference
Building Large Scale Web Apps Managing Software Complexity