摘要:
十幾年前剛畢業不久,我從事第乙份軟體開發的工作,要完成乙個專案,但沒有任何軟體設計的思路,於是請教我的老闆。我的老闆給了我兩種思路:1)先假設軟體已經做出來了,想好軟體的外在表現,由此倒推軟體的實現方法;2)思考程式的資料結構,先設計資料庫,然後再搭建軟體的上層建築。老闆給了我很大的啟發,隨著工作的開展,後來我又發現了第3種設計的思路。本文將為你分享三種軟體設計的思路:1)由頂而下;2)由底而上;3)由中間到上下。
5.1 我的第一次商業軟體的設計經驗
2023年剛畢業不久,我從事第乙份軟體開發工作,當時要負責乙個大型桌面軟體,但不知道應該如何開展軟體設計工作,於是向老闆請教。老闆也僅僅是年長我幾歲,不過公司的核心產品是老闆開發的,老闆說他其實也沒有什麼系統的方法,不過有兩種思路供我參考:
1)先假設軟體已經做出來了,想好軟體的外在表現,由此倒推軟體的實現方法;
2)思考程式的資料結構,先設計資料庫,然後再搭建軟體的上層建築。
上述的兩種軟體設計思路,相信很多有軟體設計經驗的朋友都能體會到。後來我又體會到第三種的設計思路,後文將會為你分享我對這三種設計思路的一些體會。
5.2 n層架構是怎麼回事?
這三種設計思路都與軟體系統的n層架構有關係,我們以常見的四層架構為例子,請看圖:
圖5.1 四層架構
這個是uml的包圖(package diagram),圖中好像資料夾的那個東西就是「包」,包與包之間的虛線箭頭表示的是依賴關係。
上圖表示的意思如下:
1)四層架構的四層,分別是指:表現層、邏輯層、資料訪問層和資料層;
2)表現層依賴於邏輯層,邏輯層依賴於資料訪問層,資料訪問層依賴於資料層。
那「依賴」是什麼意思呢?
「依賴」可以是以下情況之一:
1)a需要呼叫b的方法,則a依賴於b;
2)a的方法中某些引數的型別是b,則a依賴於b;
3)a的某些方法的返回值型別時b,則a依賴於b。
這樣我們大概了解了四層架構是怎麼回事了,但我們還會有以下問題:
1)表現層如何將資料傳遞給邏輯層?
2)邏輯層如何將資料傳遞給資料訪問層?
3)資料訪問層如何將資料傳遞給資料庫?
通常我們不會這麼老土通過一大堆引數來傳遞層與層之間的資料,通常我們會將資料裝在實體類中,通過實體類來傳遞資料。所以圖5.1可以進一步表示為圖5.2:
圖5.2 四層架構與實體類
補充說明一下什麼實體類?
實體類通常是乙個只有屬性沒有方法的類,通常我們會將某一業務物件的資料裝在乙個實體類中。例如:某請假單實體類,該類可能有請假人姓名、請假起止時間、請假類別和請假事由等屬性。
5.3 「由頂而下」的設計思路
看了圖5.1和圖5.2,你大概就清楚了什麼是軟體的「頂」?什麼是軟體的「 底」?「頂」就是表現層,「底」就是資料層。那麼「由頂而下」的設計思路,其實就是先想清楚軟體的表現層,然後再思考邏輯層、資料訪問層、資料層的實現。
前文我們提到要「需求驅動設計」,這個說法有點籠統,我們需要進一步思考:「什麼需求」驅動「什麼設計」?
請看下圖:
圖5.3 由頂而下的設計思路
這是uml的活**,橫線將圖分成了上下兩部分,上部分是需求分析,下部分回答了「什麼需求」驅動「什麼設計」的問題。
說明一下:「需求驅動」及橫線不是uml圖的標準語法,圖加上這些非uml元素是為了更好地表達問題。
「需求分析」這個活動有三種工作產品,分別是:
1)用例/使用者故事;
2)業務流程圖;
3)業務概念圖。
你可以理解為上述三種工作產品是「需求分析」這個活動的「輸出」。
「用例/使用者故事」和「業務流程圖」是「規劃介面」這個活動的「輸入」;類似,「業務流程圖」和「業務概念圖」是「設計邏輯層」這個活動的「輸入」。其他就不再多解釋了,你應該可以看懂這個圖了,後續幾個圖的語法類似,也不再解釋了。
上述是對圖5.3語法及表達意思的基本解釋,這裡再稍微小結一下:
1)分析需求是設計的開始,我們還需要將需求至少分解為三部分:軟體要滿足的功能(用例/使用者故事)、業務流程(業務流程圖)、業務概念(業務概念圖)三部分;
2)設計不同的層時,主要依賴的需求是不太一樣的,上述分解的三部分需求對不同的層設計提出了不同的要求。比方說:設計資料庫時主要是根據業務概念來設計的,規劃介面時主要根據軟體需要滿足的功能點,還有業務流程來設計。
5.4 「由底而上」的設計思路
經過前面的鋪墊後,這個「由底而上」的設計思路,相信你一看圖就可以懂了。
圖5.4:由底而上的設計思路
這個圖也分成了上下兩部分,上部分的內容其實和圖5.3是一樣的,只是左右順序不太一樣而已。
5.5 「由中間到上下」的設計思路
這種設計思路是我從事軟體研發工作若干年後才認識的,當時是因為專案出現了特殊狀況,為了應對這樣的狀況而採取的一種設計方法。
案例分享:客戶要改sqlserver為oracle
簽訂合同時,我們和客戶約定的專案技術架構是.net+sqlserver,當時客戶沒有反對,我們就按這樣的技術架構完成了系統,並且部署上線。但是不久客戶居然提出了這樣的要求:要求我們使用oracle資料庫,而不能用sqlserver資料庫!我們通常是按照「由底而上」的思路來設計軟體的,如果資料庫要更換,基本上整個軟體就等於重做!
如果你遇到這樣的狀況,你會怎麼辦呢?能不能按需求變更來處理呢?只有客戶願意付錢,我們就願意幹!但客戶願意付錢嗎?這可是要付推翻重做的錢啊!!
最後我們的領導決定免費重做,領導決定免費重做的原因是:
這是公司的乙個核心專案,我們期望這個專案將來能產品化,能持續賺錢。但我們技術選型主要是根據我們當前的技術情況來決定的,沒有充分考慮客戶的情況。客戶是某重要行業的企業單位,單位體制內的所有企業基本都是用oracle的,但我們選擇「視而不見」,選擇了我們最熟悉的sqlserver來開發系統,其實遲早是要遇到問題的。客戶除了用我們的系統,還會用其他更大型的更重要的系統,客戶的其他系統基本上都是使用oracle資料庫的。所以如果我們要在這個客戶領域開啟市場,將專案做好,就有必要將系統改造為oracle資料庫。
但是我們已經有部分客戶使用了我們的基於sqlserver的系統了,將來也有可能會有部分客戶要求用sqlserver,所以我們領導決心改造軟體的架構,要讓我們的軟體可以支援sqlserver,也可以支援oracle!於是我們按照「由中間到上下」的思路,重新打造了軟體架構,請看下圖:
圖5.5 由中間到上下的設計思路
這個圖也分成了上下兩部分,上面部分和前面的圖內容也是一樣的,但下面部分就很不一樣了,而且可能比較難理解。
「由中間到上下」基本的思路是這樣的:
1)先不考慮表現層,也不考慮資料層;
2)先定義實體類和資料層介面;
3)介面定義好後,往上可以設計邏輯層和表現層,往下可以設計資料層介面的實現和設計資料庫。
按照這樣的設計思路做出來的軟體架構,應該是這樣的:
圖5.6 由中間到上下的系統架構
圖中見到資料操作層介面有兩種不同的資料庫實現,分別是sqlserver和oracle,如果要考慮第三種資料庫,那麼再增加乙個實現就搞定了,而系統的上層建築(表現層、邏輯層)不需要改變。
這樣的設計方式看上去很酷,是不是應該所有系統都要考慮用這樣的方式來打造呢?
不是滴,這樣的設計方式是有缺點的:
1)系統將不能充分利用資料庫的特性,一般會禁止在資料庫中寫儲存過程、觸發器、甚至是檢視等,程式的的效能其實會降低;
2)因為不能充分利用資料庫本身的特性,所以大部分甚至是全部的業務邏輯只能靠程式搞定,這樣其實增加了程式的複雜度和工作量。
所以每種設計方法都是有針對性的,都很難做到十全十美,一般只能針對主要矛盾做出一些取捨。
5.6 小結
如果系統沒有多資料庫的要求,我會比較建議你用「由頂而下+由底而上」的設計思路;如果程式需要支援多資料庫,那麼可能考慮「由中間到上下」。上面介紹的三種設計思路,其實在實際工作中我們往往不會只選其一,往往是結合了多種思路的。不要侷限自己的思路,軟體設計的可能性是無窮的。
軟體設計是怎樣煉成的(4) 軟體設計的「大道理」
摘要 十幾年前剛畢業不久,我從事第乙份軟體開發的工作,要完成乙個專案,但沒有任何軟體設計的思路,於是請教我的老闆。我的老闆給了我兩種思路 1 先假設軟體已經做出來了,想好軟體的外在表現,由此倒推軟體的實現方法 2 思考程式的資料結構,先設計資料庫,然後再搭建軟體的上層建築。老闆給了我很大的啟發,隨著...
軟體設計是怎樣煉成的(1) 什麼是優秀的設計?
摘要 某專案的設計文件評審會上,各路技術大牛進行了 熱烈 的討論,討論的焦點是怎樣的設計才漂亮!大家圍繞著如何oo,如何高內聚低耦合,如何反轉控制等話題進行了 熱烈 的爭論。照這樣開下去,這個評審會豈不是變成了 神仙大會 怎樣的設計才叫優秀的設計呢?大綱 1.什麼是優秀的設計?2.優秀的設計能節省專...
軟體設計是怎樣煉成的(1) 什麼是優秀的設計?
摘要 某專案的設計文件評審會上,各路技術大牛進行了 熱烈 的討論,討論的焦點是怎樣的設計才漂亮!大家圍繞著如何oo,如何高內聚低耦合,如何反轉控制等話題進行了 熱烈 的爭論。照這樣開下去,這個評審會豈不是變成了 神仙大會 怎樣的設計才叫優秀的設計呢?大綱 1.什麼是優秀的設計?2.優秀的設計能節省專...