當前位置:
首頁 > 知識 > 軟體架構設計中要注意的六個方面

軟體架構設計中要注意的六個方面




  今天和師弟聊天聊到他們項目開發,有些同事總是提前考慮性能優化,需求變更又是一大堆的重寫,讓我想起了Donald Knuth 提到的:對軟體的過早地優化是萬惡的根源。這裡就簡單的說幾條重要的軟體名人哲學。


 

 

1:軟體中唯一不變的就是變化。

  在軟體開發過程中需求是不停的變化,隨著客戶對系統的認識,和現有開發功能和軟體的認識,也許以開始他提出的需求就是背離的。記得網上有一句笑話,師說需求變化的:



程序員XX遭遇車禍成植物人,醫生說活下來的希望只有萬分之一,喚醒更為渺茫。可他的Lead和親人沒有放棄,他們根據XX工作如命的作風,每天都在他身邊念:「XX,需求又改了,該幹活了,你快來呀!」,奇蹟終於發生了,XX醒來了,第一句話:「需求又改了


  在設計和架構中,凡事無絕對,作為架構師或者項目負責人你必須永遠的清晰認識到沒有完美的架構和設計,沒有萬能的軟體。只存在當前環境,需求方案,團隊人員素質,物理環境,安全等綜合因素下的合適方案,由於總總原因你的解決方案可能不是某一個單一因素下的最優解。站在這個位置你需要做的是找到這個綜合下的最優解,權衡。不要只從表面說某個人某個團隊的解決方案怎麼查怎麼不好,或者這就是當時綜合因素的最優解,站在同樣的位置環境你不一定做得更好。在架構設計和人生,在我看來很相似,總是有一堆抉擇,每一次的抉擇都會帶來得和失,權衡得失取捨。


 

 

2:KISS:(Keep It Simple,Stupid):


  保持簡單,但不過於太簡單。在《UNIX下的編程哲學》中提到很多保持設計簡單,我們能清晰看到這條原則。現在視覺設計,都崇尚簡約設計,簡單而不庸俗,而不是一大堆的豪華奢侈打造。VB編程開始的可視化設計,可見即可得,google的首頁,商業風格。在我們的軟體設計中也需要簡潔的設計,用戶需要的是可見可量化的功能的正確性,而是你運用了多牛b的技術模式,但絕不是一味的太過於簡單。你想把意見簡單的事情做複雜化是很容易的事情,但是把一件複雜的事情簡單化卻不那麼容易。簡單的人生就是幸福。但是這裡需要說明的是簡單是優秀的,但簡單是有底線邊界的,超過底線的簡單也有變得稚幼。比如事務性腳本模式比其他3中常見模式都簡單,但往往複雜的需求它不是最優解,因為他太過於簡單了(如果你還不了解是事務性腳本可以參見這裡架構設計-業務邏輯層簡述)。


 

 

3:面向抽象編程。


  在設計模式,架構模式,OO中都是一條完全的主線,作為oo第一原則存在。我不起那個軟體牛人曾說過:請牢記沒有介面的話就不要開始實現。這句話也許過於偏激,但是如果你介面理解為不變或者不易變的話,理解或契約(公司和你的合同)更貼切些吧(可能是一個不變的類,如果你能肯定的說出你的這個實現在以後,在項目開發維護中是不會變得,我覺得這也是介面,介面在於不變和不易變),你也許會同意這句話。對於目前的需求你肯定能夠沒有抽象沒夠介面完全寫出完美的代碼,但是第一條中我們說明的軟體中唯一不變的就是變化,在未來的需求中你能夠很好的一樣的優秀嗎?如果不能,那麼我認為面對當前需求就該為以後提供擴展延伸。


  我個人理解23中設計模式中大多數基本都是圍繞著這個Program to an interface, not an implementation(依賴介面而不是實現)第一原則為目的。當然我們也不能不說還有第二原則:組合優先於繼承。以後的什麼DIP(依賴倒置,IOC的原則),LSP(里氏替換),OCP(開閉原則)等等都是他們的延伸和擴展。在追溯的話這一些列都是為了軟體系統「高內聚,低耦合」(可以簡敘述為:功能完備(高內聚)的對象之間是靠介面(低耦合)通訊交互的),內聚是描述的功能性完備程度,耦合是表述模塊間的依賴程度。這裡插一句話某同事給我說依賴介面不是還有依賴嘛,我希望的是沒有耦合,我的回答是:計算機二八原則說明了這一切,既然事務出現在一起了,那絕不是偶然情況,所以他們之間必定存在依賴,在軟體設計中我們所能做的就是引入中間對象使其變為間接依賴,而減少他們之間的依賴,而我們希望這個中間對象是個相對穩定的,設計中一切都是一個詞:間接,分層,mvc,mvp,soa,中間件等等都是體現直接依賴變為間接依賴。說這個話題的原因是引出我們「高內聚,低耦合」行之有效的方法SOC(分離關注點),這不只是OO的任然對面向過程編程行之有效,他是在20年前 SP(結構化編程)中提出來的。


  如果你想對設計原則有更多的了解,可以參見這裡面向設計原則理解和一些軟體設計的原則。

 

 4:首先考慮可維護,延伸性,事後優化


  這裡也是本文的起因,正如開篇所說,Donald Knuth 提到的:對軟體的過早地優化是萬惡的根源。在開發的時候我們不需要進行任何性能的優化,即使你認為這裡可能存在性能的瓶頸,你需要考慮的更多的是設計的擴展和延伸性,以後的繼續添加新功能和維護。對於用戶需話要的需求,性能優化很多時候只是作為一個更好的體驗存在。只有當真正出現性能瓶頸的時候,你才需要做性能的優化。一個可延伸可擴展,層次分明,代碼清晰的模塊,對於你的優化也是件容易的事情,在對項目後期對於項目的總體需求明白下你也有得到更多的優化方案。在重構模式中同樣也提倡時候優化。過早的優化導致你的項目會越陷越深,到最後才知道用戶其實根本不需要這麼高的需求,或者是用戶根本不常用的功能模塊。優化也需要有標準,多少時間是用戶能忍受的,目前是多少時間。往往用戶對性能要求的只有那個少量常用的操作,而對於功能性需求的變更卻是無止境的,維護成本卻是高昂的。


  最後說一句,經常有人說反射性能低下,對我們必須承認反射比其他方案性能是不好,但是我們有解決方案:緩存。在則說性能低下,是以什麼什麼標準?用戶的接受程度?反射我們可以有其替代方案Emit,Expression tree。從反射,Expression tree,Emit的選擇,其使用難度在提升,開發效率在增加,性能在改善。本人一般卻傾向於Expression tree,兩種劇中吧。


 

 5:繼承是為了多態而不是重用


  OOP中可以編寫一個類,然後我可以不斷的繼承重用去擴展新需求。這是類的重用,是全部的重用?重用這個詞看上去也許更加的微妙。多態是面向對象的核心特徵之一,也不記不清那裡聽到的:重用只是繼承的附帶功能。在我們的繼承體系中不宜龐大如果一個擁有4,5層的繼承體系,對你的理解也增加難度,而且集成體系必須是個乾淨的繼承體系,滿足LSP(里氏替換原則):在所有用到父類的地方都可以替換為子類,還能正常準確工作。這就要求你繼承更多的是修改擴展父類的行為,盡量避免狀態。繼承只是不要為了重用的為目的,在恰當的時機更好的辦法是實現一個完全的類來替換不能滿足現有需求的類。這也是oo原則第二原則吧,組合優先於繼承。組合比如設計模式中的策略模式,你得到的是一個演算法組合功能個數是一個笛卡爾積。但也是絕對的組合,只是優先,不是取代,軟體和現實世界都是充滿了矛盾的,就如開篇第一條「軟體中唯一不變的就是變化」就是最大的矛盾,來自辯證唯物主義,你要做的是權衡。組合表述的是整體的替換,如策略模式模式的演算法整體替換。繼承是部分的少量的擴展修改行為,比如設計模式中的模版方案,在父類的流程控制下,部分步驟的修改,數據,事務的流轉控制權在父類。這條在最後說一句:設計模式不是萬能的,只是前人的優秀經驗,是依賴於場景存在的,了解設計模式我覺得更重要的是其使用場景,在遇見同類場景的時候知道可以有這種模式作為解決方案或許更好,僅作為供你選擇的解決問題方案。


 

 

6:用戶的一切輸入都是萬惡的


  用戶的輸入是屬於我們系統之外的,是無法控制的,是不可羅列的。對於用戶來說軟體只是一個黑盒子,不需要,也沒必要了解具體內在實現。對於汽車銷售人員不需要了解發動機螺栓是怎麼上的一樣,他了解宣傳的是能有什麼優勢,能給用戶帶來那些方面的滿足,價格?性能?速度?豪華?….對於門戶網站來說你對應的用戶不僅是可信任的用戶,可能還有競爭對手黑客攻擊行為。如果你的系統信任於用戶的輸入,早晚一天總會「紙包不住火的」,用戶有意無意的一次輸入就可能導致你系統的功能性的全盤崩潰,你不應該限制用戶的操作,你是不能命令用戶該輸入什麼不能輸入什麼,比如某天某人使用用戶可能降工資了或者挨批了,心情不好,你也許會潛意思的對你的系統進行挑戰。


  說到這裡隨便說一句,以前項目組有人層提過由於自動化測試伺服器運行時間太長了,把部分驗證等邏輯移到單元測試中保證。對於我的理解來說自動化測試近似於集成測試吧,功能性測試,應該是黑盒子。在單元測試中我們總是假設輸入是正確的,某個依賴也是正確的,驗證輸出的正確。而集成測試重點在於這一些都是層次的組合,貫通,不存在假設的正確性,只有來自測試人員的測試用例得到預期的輸出。


  今天就寫到這裡吧,還有很多但是一下想不起來,後續有機會的話對於重要的也會繼續補上。


  現實是矛盾的,沒有完美的設計,也沒有絕對的簡單。生活也是如此就如:簡單就是幸福,快樂就是幸福。那麼簡單的標準是什麼?怎樣才是快樂?這在於你自己的抉擇,權衡。想起了某次面試和小公司面試官談話,面試官說ORM存在性能問題,而且一直在糾結的說反對DDD,反對模式。本人先說了如果存在了性能問題有什麼解決方案,首先怎麼做如果不能滿足再怎麼做,從索引緩存到分表服務集群,再總結性的一句話:架構如人生,總是要面臨得到取捨。


via:http://www.cnblogs.com/Leo_wl/archive/2012/06/02/2532336.html


喜歡這篇文章嗎?立刻分享出去讓更多人知道吧!

本站內容充實豐富,博大精深,小編精選每日熱門資訊,隨時更新,點擊「搶先收到最新資訊」瀏覽吧!


請您繼續閱讀更多來自 全棧開發者中心 的精彩文章:

泛型的意義和作用是啥?
前端必知的Emmet實用操作
MongoDB常用語句
CSS常見布局解決方案

TAG:全棧開發者中心 |

您可能感興趣

複式樓樓梯的尺寸設計注意事項
國企混改之員工持股需要注意的四個要點
穿衣搭配的幾個注意要點!
身體有這種形狀的指甲要注意
使用廣角鏡頭要注意的6個問題
改名需要注意哪些方面?
新手父母照顧寶寶需要注意的三個方面,最後一個方面特別重要
女人經期這六個方面一定要注意
要注意,身體這3個部位最影響運氣
脫髮治療一定要注意9種體質區別
人體不能受冷的幾個部位,一定要注意!
這個時間還惡露不凈?4個方面要注意
玄關設計的注意事項是
裝修完驗收需要注意什麼?6個注意點和8個攻略不容錯過
職場新人一定要注意的幾個問題
加盟美甲品牌開店要注意哪些方面
男生面試著裝注意事項 這些點要看看
注意事項:5個方面搞懂胰島素注射
新手學習平面設計要注意哪些技巧?
冰箱嵌入櫃體散熱問題要注意