也談系統設計的一些原則

在進行系統設計時,不僅要考慮軟件的功能性需求,還要考慮非功能性需求,比如軟件的性能(Performance)、可擴展性(Scalability),系統的穩定性(Reliability)、部署(Deployment)和更新(Upgrade),可維護性(Maintainability),版本的管理,系統的安全(Security),界面的友好程度可用性(Usability, User experience)等。要想覆蓋所有需求,實現一個簡單而優秀的系統,可謂艱難。

 

大道至簡,合適最好

   什麼是優秀的系統設計? 這個問題頗有爭議,但幾乎每個軟件工程師和架構師都追求優秀的系統設計。當然,系統設計並不代表結果,系統設計只是架構師或者帶頭程序員的工作,優秀的系統設計必須經由良好的項目管理和團隊努力,經過分析需求、設計、開發、測試、分發、維護,以及迭代或重構的過程。中間哪個環節出了問題,再好的設計都將功虧一簣。

可能每個人都對自己設計的系統很自信很滿意,但“實踐是檢驗真理的唯一標準”。如果一個系統設計經過實踐證明,大家(指客戶或用戶)公認爲優秀的系統,那就是一個優秀的系統設計。

大道至簡,適合的就是最好的。其實設計並沒有那麼嚴重,適合的就是最好的,簡單最好。軟件也是一種服務,這個系統設計出來就是爲了服務一些用戶還沒有被滿足的需求,如果你能夠恰好滿足了這些沒有被滿足的需求,而且能以比較低的代價提供這種服務,那這就是最好的系統。因爲系統設計的來源是商業需求,而商業追求利益最大化。你的軟件和服務必須比別人功能更加先進,更加好用,對變化的商業 需求反應更加靈活,推出或者升級的速度更快,開發和維護成本更低,才能證明這個系統設計的優秀性。所以系統簡單,不能說明你的系統不優秀,說不定設計者有化繁爲簡的過人能力;系統複雜,功能繁多,也不能說明系統優秀。

技 術人員常常犯的錯誤是技術至上,技術第一,不計成本的去設計和開發無比先進和靈活的系統,不計風險的去採用最新的沒經過實用的新技術。所以作爲架構師,不僅僅需要精通技術,更需要良好的溝通協調,去了解業務和客戶真正的需求,真正站在客戶利益角度和最終用戶利益角度思考問題和設計系統,在各種選擇中做出權 衡。

極限編程人士的一個響亮的口號是“You aren't going to need it”。這其中包含的核心意義就是不要爲了考慮程序的可擴展性,把目前不需要的功能加入到軟件中來。不要過度設計。抓住重點,合適就好。比如根據二八原則,80%的用戶只會使用20%的功能,而這20%的功能就是客戶最關注的最需要的功能,也就是軟件或服務的“賣點“,系統設計時必須集中精力和充分考慮到這部分需求。如果把精力放在某些花哨的功能上,既不 重要,也沒必要,那就是過度設計。要想避免過度設計,我覺得可以遵循敏捷開發方式來做。儘可能的簡單設計,當滿足不了時,重構;保證產品是可運行的,不斷的加入新的特徵;產品經常性的提交給客戶使用。

 

穩定壓倒一切

   標題黨的風格,但這個口號在社會上如此,系統設計上也是如此。系統的穩定性壓倒一切,即使犧牲性能,也要確保系統的穩定。即使擴展性不強,也要保持系統穩定。即使用戶界面不友好,也不要系統不穩定。

爲什麼用戶這麼關注穩定性?由於人們日常的工作對系統依賴程度越來越多,因此係統必須可靠。舉個例子,我想我們都玩過CPU超頻吧,頻率高了確實挺爽,但如果一天死機幾次,正在乾的活全部丟失,你心裏還會放心踏實的工作嗎?同樣的道理,一個網站如果不穩定,經常宕掉,用戶的信息和辛辛苦苦寫的文章搞丟失,還會有人上這個網站嗎?所以穩定性是系統設計最重要的方面。

 但實施起來比說起來困難,有時候爲了實現系統靈活的擴展性,導致系統架構不穩定;也有時候爲了實現高性能,導致系統不穩定。如何取捨和平衡,不同的需求,不 同的架構師會做出不同的抉擇。但個人認爲穩定性放第一位,再先進靈活的框架,再牛的功能,如果不夠穩定,堅決不要沒有充分測試匆忙上線。

系統穩定性如果獲得?除了大量充分的測試以外,在設計上必須有針對可靠性的設計,基本原則是在儘量保證各服務可靠的基礎之上,通過一個健壯的體系結構來確保系統能夠在硬件和軟件出錯的情況下依然平穩的運行。比如採用統一面向方面的框架,統一的異常處理、錯誤隔離、報警、容錯和恢復機制,考慮系統的冗餘度,儘可能地避免單點故障,儘可能地保證一個進程故障都不會引起系統的癱瘓,同時也允許系統對部分服務做升級和維護而不影響系統繼續提供核心的服務等等。總之,系統可靠性是系統在給定的時間間隔及給定的環境條件下,按設計要求,成功地運行程序的概率。成功地運行不僅要保證系統能正確地運行,滿足功能需求,還要求當系統出現意外故障時能夠儘快恢復正常運行,數據不受破壞。

 

可擴展性,靈活性

   毋庸置疑,一個先進的系統設計具有很強的可擴展性和靈活性,因爲現在的商業需求變化迅速,如果每次小小變化都導致大量系統改動的話,這樣的體系結構無疑是失敗的。所以架構師必須去主動迎接未來可能的變化,設計靈活的可擴展的架構。但具體系統的可擴展性做到哪個程度,以及和其他設計指標的權衡利弊如何取捨是個問題。

比如具體靈活到哪個程度的問題,是要實現對各個組件的無依賴性,是要實現對具體數據庫(File/XML/SQL Server/Oracle/DB2)的無依賴性,還是要實現對具體操作系統(Windows, Linux, OS2, AIX)的無依賴性?靈活程度不一樣,設計要求和設計方法不一樣。

架構設計必須儘量封裝可能的變化,例如在業務流程發生有限的變化時(比如每個業務模塊本身的業務邏輯沒有變的情況下),能夠比較方便地修改系統程序模塊或組件間的調用關係而實現新的需求;如果這種調用關係被設計成存儲在配置庫的數據字典裏,則連程序代碼都不用修改,只需修改數據字典裏的模塊或組件調用規則即可。這就是按需設計,不是過度設計。

設計指標的權衡利弊如何取捨的問題也很明顯,比如降低依賴性常用的方法是封裝變化(Wrapper),分層設計,但會帶來系統的性能下降,尤其是大數據量的情況下;引入緩存機制吧又會增加系統複雜性,降低系統穩定性等。因爲過於複雜的設計既造成系統不穩定的隱患,又影響性能。

這方面的討論很多,個人認爲可擴展性和靈活性設計是架構設計中非常重要的方面,但不能過度。穩定性第一,接下來是靈活性第二,還是性能第二靈活性第三的問題,要具體看需求的情況了。如果是一個實時大數據量大用戶在線服務系統,應該在性能的前提下實現靈活;如果是一個其他的業務系統,靈活性優先於性能。具體情況要具體權衡利弊。
發佈了0 篇原創文章 · 獲贊 0 · 訪問量 1萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章