本文轉自:http://impd.tencent.com/?p=100
1、軟件長期運營存在什麼問題
一個大規模的客戶端軟件的生命週期中,我們可以把它分爲兩個比較粗的時期。一個是前期的搭建軟件的時期,即從無到有的時期;第二個是搭建完成之後,進入的一個穩定的運營時期。第二個時期纔是最關鍵的,在這個時期我們會持續的迭加需求,持續的優化功能,而且第二個時期也是代碼在慢慢變質的時期。 在這個時期,你可能會發現:我們的軟件慢慢出現模塊耦合嚴重,牽一髮而動全身;每個版本都會涌現出老功能的BUG,你沒動過的模塊也會出BUG;或者改了一個小問題了,帶出來很多其他問題;缺乏擴展性,往老模塊加新功能非常痛苦;程序的崩潰率越來越高;新員工接手老模塊經常不能理解原來的設計思想而改壞;移植一個DLL到另一個軟件時,發現必須連帶也移植十幾個DLL。本文將分享對於這些問題的思考與方法。2. 軟件的積木模型
一個運營型的客戶端軟件,做出來就是爲了長期運營,需要不斷的迭加功能。而不是做出來,兩三年就重寫一次。那麼這樣一個軟件就像堆積木一樣。一個軟件剛開始寫了兩千行代碼,感覺設計得非常好,模塊化擴展性都非常好,性能也非常快,都能很好的面向運營。寫了兩三年之後,就會出現像這種積木一樣的結構,很容易崩塌。所謂重構,形象的說,可以看做是某個積木不穩定,要往裏塞一塞。那麼整個開發過程,就是一個不斷迭代、不斷優化、不斷重構的過程。對於我們這個積木模形,有什麼辦法不讓一些木條跑出來,這也是我們需要想的思路。我們是不是可以先圍四面牆,然後在牆裏面再去塔積木?3. 導致代碼變質的兩大因素
團隊中總是會存在這樣那樣的問題,這些問題最終總是影響到我們的代碼朝着不良的方向發展。對於這些因素,我可以將它們抽象爲兩大類。一類是人的因素:比如架構設計不合理,需求沒考慮清楚,項目進度壓力,溝通問題,缺少文檔、培訓,等等。另一類是時間的因素:比如人員的變動,需求的長期迭加和變更,等等。人的因素是由於人本身的素質或疏忽導致,時間因素是由於時間的長期推進導致,即使人的素質很高也必然會出現時間因素的問題。4. 代碼變亂的微觀原因
在上述兩大類因素的長期作用下,最終會導致代碼越來越亂。如果從微觀的角度來剖析,這跟依賴有着很大的關係。代碼的變亂,根本原因就是由於太多不良依賴或者模塊失去單一性所致。我們來看一下依賴是如何產生的。-
依賴的方式
依賴的方式也可能是多種多樣的,單向依賴、雙向依賴、環狀依賴或者一個依賴於多個。下圖也是一些示例,現實的代碼中可能是由各種依賴方式組成的非常複雜的網狀結構。
-
依賴的變化
我們的代碼從設計之初到現在,中間經過了幾年的時間,代碼變得越來越亂很大的原因是因爲這種紅線的持續出現。本來有很多獨立性很好的模塊,變成了錯綜複雜的網狀結構。
前面是沒有引入新組件的情況,如果引入了新組件,必然會引入新的引賴,那麼就要好好的去界定,引入的新組件是屬於哪個層面的。像下面第一個圖,新引入的組件依賴於原來兩個組件是在最上層,第二個圖新引入的組件是在中間層,第三個圖新引入的組件被另外兩個組件依賴在最底層。
引入新組件,其實應該做好充份的考慮,而不是讓開發人員隨意的引入。需要充份思考引入的新組件應該放在哪一層面纔是最合理的,才有利於以後的擴展和移植。 可能讀者會遇到這種情況,一個功能編譯沒有問題,測試也沒有問題,發佈後一兩年也沒有問題。當我們要把這個功能移植出來的時候,才發現問題大了。你想移植一個組件到另一個軟件時,必須連帶也移植十幾個組件。
5. 如何解決依賴
-
組件網圖
如果組件網圖中存在錯誤的依賴關係,或者如果有需求要求圖中的組件h依賴於g,應該怎麼辦?可以通過下面的“分解適配”和“升級降級”的方法進行解決。
-
分解適配(單一職責)
-
升級降級
6. 處理依賴的方法論
-
通用的模塊不要依賴於不通用的模塊
-
之前的創建模塊儘量不要依賴於後創建的模塊
-
需要進行微觀分層(組件網圖)
7. 增加功能三步法
我們拿到一份需求,需要增加一個功能,應該怎麼做?如果新功能與原先的模塊有依賴的時候,如果是經驗欠缺的同事,他們會怎麼去做呢?會不會考慮說架構會不會合理?經驗欠缺的同事可能通常都不會這麼考慮,他們只是集中於能不能把需求實現,而不是考慮這樣用架構上合不合理。團隊就應該有規範去約束經驗欠缺的同事不去犯錯誤。這裏有一個增加功能的三步法供讀者參考,這些方法可能不完善,讀者可能有更好的方法,應該尋找適合自己團隊的解決辦法。-
不修改依賴,不修改或增加接口
-
不修改依賴,但增加接口
-
修改內部依賴