軟件設計是怎樣煉成的(5)——規劃系統的骨架(架構設計)(下篇)

摘要:java

概要設計和詳細設計,多是最開始據說的設計,但後來發現若是侷限在這兩個設計的框架下,可能會有諸多不順,咱們須要架構設計、數據庫設計、模塊設計和用戶體驗設計,本文主要分享架構設計,此文有點長,因此分拆爲上下兩篇,下篇爲你分享:在」需求驅動「如何作出初步架構設計、如何逐步細化這個設計、分佈式與單機系統架構設計的區別等。算法

 

大綱:數據庫

1.什麼是優秀的設計?
2.優秀的設計能節省項目工做量
3.優秀設計從分析需求開始
4.軟件系統不是木桶型的
5.軟件設計的「大道理」
6.規劃系統骨架——架構設計
7.打造系統的底蘊——數據庫設計
8.細節決定成敗——詳細設計
9.用戶感受好纔是真的好——用戶體驗設計
10.持續提高設計水平服務器

 

本文章是系列文章之一,若是你尚未看過以前的文章,建議先看完前面的文章再看本篇,這樣效果更好。架構

 

 

6.規劃系統骨架——架構設計

 
 
6.5 逐步拆解架構設計
 
需求驅動設計
有這樣的一句話:不以結婚爲目的的談戀愛是耍流氓!
這句話與軟件設計有什麼關係呢?頗有關係呢!由於有另外這樣的一句話:不以解決需求爲目的軟件設計就是耍流氓!
因此若是不想被人家說你耍流氓,你須要瞭解需求,須要「需求驅動」地思考設計問題。
 
前文咱們從需求中發現了四個設計點,一塊兒來回顧一下:
1)用例圖中提到,員工能夠經過移動設備提出請假或外出申請,領導能夠及時收到審批的提醒。那麼咱們應該如何設計「即時瞭解」和「及時收到提醒」呢?解決方案可能有:短信提醒、郵件提醒、或者二者同時提醒。
2)需求中要求員工能夠經過移動設備提出申請,領導也能夠經過移動設備完成審批?咱們要思考,爲何須要移動設備完成這些工做呢?什麼狀況下才須要經過移動設備完成這些工做呢?咱們的解決方案是怎樣呢?經過短信、手機上網,仍是經過手機的APP來搞定?
3)請假申請和審批流程,跟流程相關的均可以扯到「工做流」。工做流能夠是一個很「恐怖」的話題,你打算作一個"死"的工做流,「半死不活」的工做流,仍是「全活」的工做流呢?你打算從零開始作,仍是買一個工做流引擎呢?
4)權限要作成重用已是有必定難度的,同時還須要考慮與工做流的結合,還要考慮工做流也能夠作成重用,難度很高啊!那到底要不要考慮作成重用,而且權限和工做流能結合起來呢?
 
補充說明一下工做流:
1)死的工做流:就是代碼寫死的(hard code),數據庫設計也是死的,流程或表單有任何變化,均可能須要改代碼和數據庫設計。
2)半死不活的工做流:部分地方寫死,部分地方是靈活的,能適應部分需求變化。
3)全活的工做流:代碼和數據庫設計等都是靈活的,能基本適應流程及表單的變化,不須要修改代碼或數據庫設計,只要配置一下就能夠搞定。
沒有任何工做流技術積累的狀況下,要作到「全活的工做流」是很高難度的,通常不要在當前項目中就定下這樣的設計目標,基本是實現不了的。能夠分階段來作,先寫「死」,而後「半死不活」,最後才追求「全活」。
 
初步架構設計(第一層拆解)
咱們再次回顧一下,什麼纔是優秀的設計?
我在前文中提到,一個優秀的設計應該具有如下特色:

1)優秀的設計都是需求驅動的,不熟悉需求就作出來的設計是不靠譜的;
2)優秀的設計應該是當前團隊能理解能實現的,太超前的設計項目團隊作不出來,這個設計只能是擺設;
3)優秀的設計應充分考慮當前各類限制條件,適當作出平衡,能保證達成項目的目標:
4)優秀的設計能儘可能下降項目的總體工做量,讓整個項目更加可控。框架

咱們嘗試一下,儘可能按上述標準來完成這個設計吧!數據庫設計

我打算用 .net(開發語言採用 C#) 及 SQLServer 來開發這個系統。
你可能會問,爲何你選擇這個開發語言和數據庫?這些不是須要論證,須要作方案選擇的嗎?
咱們不是搞理論或學術研究,一個真實項目的狀況是這樣的:你接手項目時合同已經簽下來,合同中會規定用什麼技術框架的,包括開發語言與數據庫,通常不會不定下來的。而定下來的技術框架,通常就是大家公司最熟悉的那種,而你接手這個項目,通常是熟悉這個技術框架的。公司不會這麼傻,選一個本身公司一點都不熟悉的技術框架來完成項目,客戶更加不會這麼傻選一個不懂這個技術架構的軟件公司,你的上司也不會這麼傻找不熟悉這個技術架構的你來負責這個項目的設計。
一個系統到底用.net好一點,java好一點,PHP好一點?這些其實沒有定論的,通常來講就是你熟悉哪一個就用哪一個!哪一個你最有經驗最有成功案例就用哪一個!針對具體一個項目作架構設計時,不能脫離具體的技術框架,要先肯定你的開發語言、數據庫種類等。架構設計要從物理設計的深度來思考,而不能僅僅是理論設計或者是邏輯上的設計,不然又會犯了太空洞的毛病(即「放之四海而皆準」的毛病)。
 
如下是初步的架構設計,這個設計並非怎樣「驚天地泣鬼神」,僅僅是我以爲咱們能作到的也能應對需求的一個設計。
 
圖6.6 初步的架構設計
 
圖中標記出來的一、二、三、4,分別對應對前面的設計關注點一、二、三、4。此圖對設計關注點一、2考慮得稍微具體一點,而對於設計關注點三、4僅僅是一個初步的考慮,由於當時咱們工做流的技術積累還比較初級。
須要特別說明的:請留意「智能手機」這個客戶端,圖中寫的是操做系統用WindowsMoble,這是一個之前的設計,在如今看來是不合適的,如今用這種操做系統的手機幾乎不存在了。需求中提到要求使用移動設備完成相關工做,那麼咱們就須要思考是什麼移動設備呢?移動設備上須要什麼操做系統?須要安裝什麼軟件等等?這些咱們都須要考慮。
 
小結一下進行初步架構設計的要點:
1)咱們的系統大部分會涉及到多個客戶端及服務器,咱們須要思考咱們的系統須要怎樣的客戶端及服務器,思考這些設備上面須要安裝怎樣的操做系統、平臺、軟件等,思考這些設備須要怎樣的硬件配置,如CPU、內存、硬盤大小等等。
2)咱們須要思考這些客戶端及服務器之間的物理聯繫方式,例如:是局域網方式、互聯網,仍是二者都支持?是HTTP或是HTTPS?等等。
3)這些設備上咱們須要開發什麼軟件、數據庫等?例如:圖6.6中須要咱們須要開發的東西有:Web Application、工做流定義用的客戶端軟件、三個數據庫。架構設計其實就是劃分系統的各部分及各部分的關係,這些內容其實就是咱們整個系統的第一次的各部分的劃分,而各部分的關係咱們能夠經過圖6.6大體能夠了解。
 
繼續深刻拆解(第二層拆解)
圖6.6已經從硬件配置、軟件各部分的劃分、數據庫的規劃等方面描述了本系統的初步架構,固然這個架構仍是太粗了,咱們還須要繼續深刻思考,請看下圖:
圖6.7 架構設計的進一步思考
 
這個系統至少有5個須要咱們開發的部分,每個部分都須要更進一步深化設計,下面咱們以Web Application爲例子,繼續深刻設計!請看下圖:
 
圖6.8 Web Application的設計
 
咱們規劃 Web Application 的內部架構時,除了考慮內部各部分之間的關係,也須要考慮內部所劃分出來的各部分,有哪些是須要和外部交互的?圖6.6中表示的各部分關係還比較粗,咱們還須要繼續細化,請看下圖:
 
圖6.9 系統各部分的關係
 
當咱們逐步細化設計的時候,咱們極可能會發現以前初步架構設計不合理的或遺漏的地方等等,留意圖6.9中紅色的部分,這是以前沒有畫進去的內容。這個圖已經更進一步細化設計了,但咱們仍然有不少問題未解決,請看下圖:
 
圖6.10 更多的更具體的設計問題
 
圖6.10與圖6.9的區別就是多了黃色的部分,請思考這三個問題:
1)權限設置的UI如何考慮?
用戶管理、權限管理的UI可考慮設計成可重用的。
界面能夠是獨立的,也能夠「嵌入」到別的系統中。
2)工做流如何設計?
還須要對工做流進行進一步的抽象。
考慮清楚工做流的對外接口。
考慮清楚數據庫設計。
3)圖形定義客戶端軟件如何設計?
圖形平臺自主開發,仍是利用第三方的?
數據如何保存到DB中?
除了上述這些問題和思考,還會有更多的其餘問題,軟件設計是充滿挑戰的工做!
 
設計初期的問題可能比較朦朧比較大,但隨着設計的深刻,問題會愈來愈多,問題也會愈來愈具體。有時候你會以爲怎麼越深刻設計,發現的問題越多,這是正常現象,並且是好事!若是沒有發現問題,這每每不是真的沒有問題了,而是咱們不具有發現問題的能力了,這是至關可怕的,要當心留意不可輕敵噢!
 
圖6.6後咱們連續進行了多步的設計拆解,這裏小結一下:
1)系統須要開發什麼軟件和數據庫等,這些是第一次對系統各部分的拆分,姑且這叫」第一層的拆解「,接下來須要繼續拆解。
2)繼續拆解時可參考分層架構,但須要拆分得更加具體,不要犯」放之四海而皆準「的毛病。這個層次的拆解,姑且叫「第二層的拆解」。
3)除了規劃好內部各部分的關係,還須要規劃內部的各部分與外部之間的關係。
4)在拆解的過程當中,問題會愈來愈多,也會愈來愈細,這是正常現象,也是好現象。
5)拆解過程當中也可能會發現以前初步架構設計中不合理或遺漏的地方,請立刻調整;有時候甚至會發現以前的設計徹底不對,那麼就要有勇氣推翻重作。
6)「第二層的的拆解」結果有多是組件(Component)、代碼包、某個分層等等,多是「物理分拆」也多是「邏輯分拆」。那麼「第二層的拆解」要多細才合適呢?其實很難有固定的標準,給一個簡單標準做爲參考:若是再拆解下去下一步的拆解就到類了,那麼就能夠認爲目前的拆解粒度比較合適了。細化到類的拆解,能夠在模塊設計(詳細設計)中再進一步考慮。
 
說明一下「物理分拆」和「邏輯分拆」:
物理分拆:物理分拆就是物理上是獨立的部分,有多是exe、dll、數據庫文件等。圖6.6中將系統分拆爲5部分,分別是Web Application、流程定義用的客戶端軟件以及三個數據庫,這就是物理分拆;咱們對Web Applicationi繼續分拆時,圖6.8中的日曆控件是物理分拆,這個控件將經過二進制的方式供程序其餘部分調用,而這個控件未來也能夠供其餘系統使用。
邏輯分拆:代碼包、某個分層這些每每是邏輯分拆,物理上它們不會編譯成單獨的一部分,而是被總體編譯進軟件當中。
 
「第二層拆解」的目的除了更加方便咱們設計出系統,另一個重要目的就是作系統的重用設計。若是是「物理分拆」,就能夠作到二進制重用;若是是「邏輯分拆」,那麼只能作到源代碼重用。這些重用不只僅爲當前軟件服務,還能夠爲未來及其餘軟件服務。
 
 
6.6 分佈式系統與單機系統的架構設計
 
分佈式系統可能有不少定義,有些資料可能也說得比較炫,文章這裏提出這個說法不是用來「拋書包」的,這裏也順便說明一下:本文中提出的一些概念(例如:第一層拆解、第二層拆解、物理分拆、邏輯分拆)是爲了更加方便說明問題而已,你們沒有必要去互聯網上搜索這些名詞的定義。
咱們開發的東西只須要安裝在一臺電腦上,這個軟件就能工做,這就是單機軟件,例如Office軟件、Photoshop軟件等;但分佈式系統每每須要咱們在多臺設備上部署,各部分須要聯調後,整個系統才能正常工做。
文中用到的案例是分佈式系統,分佈式系統如何作架構設計,相信你已經有一些體會了。單機系統的架構設計看上去彷佛更簡單一點,由於它不須要作「第一層拆解」,直接就是「第二層拆解」。其實不必定的,由於單機系統的「第二層拆解」每每是很複雜的,單機系統每每有特殊的高科技的算法、有獨特數據存儲格式等等,你能夠設想一下,你能完成Office的架構設計嗎?還有Photoshop的架構設計?
 
 
6.7 架構設計小結
 
架構設計是高難度、高技術含量的活,我以爲很難寫出一本祕籍,你看了後就能應對大部分軟件的架構設計。若是咱們不精通業務,不精通技術,沒有豐富的設計經驗,不少設計咱們將會一籌莫展。
 
小結一下分佈式系統的架構設計要點,單機系統也能夠參考:
1)咱們的系統大部分會涉及到多個客戶端及服務器,咱們須要思考咱們的系統須要怎樣的客戶端及服務器,思考這些設備上面須要安裝怎樣的操做系統、平臺、軟件等,思考這些設備須要怎樣的硬件配置,如CPU、內存、硬盤大小等等。
2)咱們須要思考這些客戶端及服務器之間的物理聯繫方式,例如:是局域網方式、互聯網,仍是二者都支持?是HTTP或是HTTPS?等等。
4)思考系統須要開發什麼軟件和數據庫等,這些是第一次對系統各部分的拆分,姑且這叫」第一層的拆解「。
5)繼續拆解時可參考分層架構,但須要拆分得更加具體,不要犯」放之四海而皆準「的毛病。這個層次的拆解,姑且叫「第二層的拆解」。
6)除了規劃好內部各部分的關係,還須要規劃內部的各部分與外部之間的關係。
7)在拆解的過程當中,問題會愈來愈多,也會愈來愈細,這是正常現象,也是好現象。
8)拆解過程當中也可能會發現以前初步架構設計中不合理或遺漏的地方,請立刻調整;有時候甚至會發現以前的設計徹底不對,那麼就要有勇氣推翻重作。
9)「第二層的的拆解」結果有多是組件(Component)、代碼包、某個分層等等,多是「物理分拆」也多是「邏輯分拆」。那麼「第二層的拆解」要多細才合適呢?其實很難有固定的標準,給一個簡單標準做爲參考:若是再拆解下去下一步的拆解就到類了,那麼就能夠認爲目前的拆解粒度比較合適了。細化到類的拆解,能夠在模塊設計(詳細設計)中再進一步考慮。
 
軟件架構設計博大精深,上述僅僅是一些規律的簡單總結,但願對你能有一點點幫助。
 

本文是系列文章的其中一篇,要作軟件設計師一點都不簡單啊,請留意後續文章!分佈式

 

若是本文對你有幫助,麻煩點一下「推薦」啦,謝謝!spa

 

 

做者:張傳波操作系統

創新工場創業課堂(敏捷課程)講師

軟件研發管理資深顧問

CMMI首席專家

《火球——UML大戰需求分析》做者

軟件知識原創基地創辦人

相關文章
相關標籤/搜索