爲什麼我們的系統複雜度這麼高了?

我曾多次聽到靈魂拷問:

  1. 爲什麼你們程序員不能一個人負責所有服務呢?
  2. 爲什麼開發這麼簡單的需求還需要這麼多人?
  3. 爲什麼服務需要分給不同的人,不能一個人可以瞭解所有服務功能?
  4. 一個項目爲什麼還需要這麼多人?

答案在一個古老的傳說中,上帝在混沌中創造了天堂和人間,而程序員創造了混沌。

軟件系統複雜度的由來

我們先看看大家是否遇到過這樣的場景:

  1. 這是2017年遺留下來的系統了,問題是非常多的,還能跑起來,就是與現在格格不入,哪哪都有問題,到處都需要改,無從下手。
  2. 這個技術升級要不要去做呢?不知如何衡量成本與收益,從價值大小入手,更多的是哪些故事更好聽,哪些優先級更高。
  3. 技術架構優化通常都是底層優化,牽一髮而動全身,測試不全面,急於上線引出更大的問題,被各方指責,直接回退,後續的優化動作被迫停止,無疾而終。
  4. 我們第一期先做一個簡單的系統MVP跑起來。兩週後,老大說了,功能需要加這些那些,還有這這的功能。還是得按照原計劃上線。

上面的場景隱含了軟件的複雜度主要兩個來源:需求功能的複雜度和技術設計的複雜度。而這兩個複雜度就是系統演進的產物。

建築師不會輕易給100層的高樓增加一個地下室,但是軟件工程師會,不但增加了1層地下室還是多蓋了5層樓,額外再加上外掛陽臺。

建築師一般只在設計階段修改圖紙,而軟件工程師在任何時候都在修改,設計時候修改,在測試時候修改,還在上線後繼續修改。這肯定會帶來複雜度的,但是最大的複雜度來自於——規模

大家熟知的朋友圈功能上主要點:發動態、評論和點贊。業務功能不復雜,但是人羣規模複雜度很高。是典型的質量複雜度高,業務複雜度低的業務。

程序員有一個笑話:

  小李跟小王抱怨,說這段代碼實在是太噁心了,花了很長時間纔看懂,並且代碼非常僵硬,而正好這個需求需要改動到這裏,代碼真的就像一坨亂麻。
  小王問他最後是怎麼處理的。小李說,我給它又加了一坨。

有一個需求,需要小王到土裏埋個地雷,這確實不復雜,但小王往往面臨的真實場景其實是:“在這片雷區里加一個雷”,而雷區裏哪裏有雷,沒有人說得清楚。

在開始地裏還沒有很多地雷的時候,風險是很小的。隨着經常埋地雷,風吹雨曬,沒有人指導之前埋下的地雷在哪裏了,這時候就是複雜度高危的時刻。

大家會想到,在軟件系統的設計前期,我們研發人員做好設計如層次、模塊劃分等,那不是解決系統複雜度的問題了嗎?

有道理!實際情況是——

  系統的複雜性與能量守恆定律是相匹配的。能量不會憑空消失,只能從一種形式轉化爲另一種形式。軟件的複雜性不會憑空消失,只會轉移到另一個地方。

我們使用微服務架構,我們儘可能複用服務,只是將複雜度從開發階段轉移到了維護治理階段

我們花費大量時間分析需求,產品設計等,那麼複雜度變成需求功能的複雜度。

整體的複雜度在外力的作用下,可以變得有序,複雜度看着是降低了,也的確降低了。但是宇宙第一定律(自封的)--熵增定律告訴我們:在孤立系統中,系統的熵在自發過程中不會減少,通常會增加

複雜度還是會增加,我們投入了人力打破了這個『自發過程』,降低了複雜度。我們投入人力,就是把複雜度分擔給了不同的人,讓每個人可以接受的複雜度屬於合理範圍。這個外力還可以通過刪減下線服務,打破『自發過程』也可以降低複雜度。

同時也需要注意到,組織規模帶來的複雜度。《人月神話》告訴我們通過增加人力資源,可以在較短時間內完成一個軟件項目的錯誤觀念。

軟件系統複雜度的分類

軟件系統複雜度的分類有很多中分類方式,《人月神話》將軟件複雜度分爲本質複雜度偶然複雜度。本質屬性是一個物體必然擁有的屬性,偶然屬性是一個物體可以擁有的屬性(也可以不擁有)。比如我們需要做一個電商系統,必然包含商品,交易和用戶等業務複雜度,這就是本質複雜度。但是我們開發過程中引入了一個新的技術和第三方而帶來的複雜度,則爲偶然複雜度。

當然還可以根據對象分爲系統複雜度、代碼複雜度、業務複雜度和組織複雜度等。

在《軟件研發行業創新實戰案例解析》書中內容:

最上層是問題域本身的複雜度,也稱爲業務複雜度,該複雜度和軟件系統本身無關,在沒有軟件的時候就已經存在了,代表業務本身。

第二層是解決方案的複雜度,指業務問題映射到軟件領域之後的解決方案,描述軟件系統處理業務領域問題的具體方法,領域驅動設計(Domain-Driven Design,DDD)就工作在這一層。

第三層是軟件的複雜度,分爲本質複雜度和隨機複雜度。

本質複雜度是軟件必須擁有的,繼承自問題域本身的複雜度,除非縮小問題域的範圍,否則無法消除本質複雜度,本質複雜度是系統複雜度的下限。

隨機複雜度是軟件可以擁有也可以沒有的屬性,由解決方案的實現過程附加產生,主要表現爲短視效應、認知負荷和協同成本,是我們需要盡力規避的部分,也是需要關注的重點。

可以看出來,這本書複雜度也是來源於《人月神話》,經典永不變!

軟件系統複雜度的度量

軟件系統的運行遠不及人體那麼複雜,哪怕是google的系統也是如此。但隨着系統規模的增大,系統的運行會變得非常複雜,遠超出一個人所能認知的範圍,在這種情況下,它們的複雜度對於人類的認知是一樣的,軟件系統和人體都可以看做是非常複雜的系統。

認知之外就是答案。

醫學領域經過多年的探索,醫生可以通過各種維度的“指標”數據來判斷真實的病因,甚至有的指標可以直接判定疾病。

那麼系統的複雜度如何度量?這目前還是沒有答案的,系統的複雜度不能像算法和程序控制流一樣使用分別時間空間和McCabe 度量法計算。

John Ousterhout(約翰-歐斯特霍特),在他的著作《A Philosophy of Software Design》中提出,軟件設計的核心在於降低複雜性。他選擇從認知的負擔和開發工作量的角度來定義軟件的複雜性,並且給出了一個複雜度量公式: 子模塊的複雜度乘以該模塊對應的開發時間權重值,累加後得到系統的整體複雜度 C。系統整體的複雜度並不簡單等於所有子模塊複雜度的累加,還要考慮開發維護該模塊所花費的時間在整體時間中的佔比(對應權重值)。也就是說,即使某個模塊非常複雜,如果很少使用或修改,也不會對系統的整體複雜度造成大的影響。

我認爲複雜度就是認知度的體現,那麼可以歸屬到信息領域,那麼就可以熵這個概念來度量。已經有科學家做了類似的研究了:《Measures of complexity:A non-exhaustive list》。

論文提出用計算能力度量複雜性一種觀點認爲,系統的計算能力如果等價於通用圖靈機的計算能力,就是複雜系統。不過,班尼特等人則認爲,具有執行通用計算的能力並不意味着系統本身就是複雜的;應當測量的是系統處理輸入時的行爲的複雜性

當然目前也沒有看到更好的方法,熵增定律會是一個解決複雜度的好思路。

軟件系統複雜度與我們的關係

之前使用過醫學領域對複雜度的處理,在中國古代還有一個傳說,扁鵲三兄弟的故事。這個故事從管理者角度來看,應該是一個長期主義的故事,扁鵲大哥的治療方法旨在預防疾病爆發,具有長遠的健康視野,但也沒有積極傳播自己的成就,以建立聲譽。

我們追求短期交付效率,使用DDD(期限驅動開發)方式,在新的創新項目上是可行的。加上對驗證失敗的項目果斷放棄放棄會更好。在這點上,我最欣佩的公司是抖音集團,可以做到快速驗證業務,而又果斷關閉業務。比如近期關閉了時光相冊、幸福裏、酒旅類電商和Shopify店面等。

《鳳凰架構》也說過:複雜性本身不是洪水猛獸,無法處理的複雜性纔是。

對複雜系統我們可以採用分而治之,對組織結構也是如此。

先進的生產力都伴隨着更高的複雜性,需要有與生產力符合的生產關係來匹配,敏銳地捕捉到生產力的變化,隨時調整生產關係。系統複雜度也是類似的,問題在技術,根子在組織

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章