第五章設(shè)計模式與軟件架構(gòu)設(shè)計
一、面向?qū)ο筌浖軜?gòu)設(shè)計思想
a)面向?qū)ο蠓妒?/p>
i.面向?qū)ο蠓妒降暮诵氖?#8220;對象”的概念
ii.所有的東西都聚焦于對象
iii.圍繞對象-而非函數(shù)-組織代碼
b)對象從不同視角觀察
i.概念層:一個對象是一系列責任
ii.規(guī)格層:一個對象是一系列可以被其他對象或該對象自己調(diào)用的方法
iii.實現(xiàn)層:一個對象是一些代碼和數(shù)據(jù)
c)設(shè)計原則軟件開發(fā)網(wǎng)
i.“開閉”原則(OCP)
ii.里氏代換原則(LSP)
iii.依賴倒轉(zhuǎn)原則(DIP)
iv.接口隔離原則(ISP)
v.組合/聚合復用原則(CARP)
vi.迪米特法則(LoD)
二、使用UML進行軟件架構(gòu)設(shè)計
a)最小UML建模技術(shù)
i.對于大多數(shù)問題而言,只需使用20%的UML,就可以完成80%的建模工作。
ii.實際中,好像總是沒有足夠的時間來完成建模、分析和設(shè)計工作,總是過早地進入到編碼階段。
iii.足以很好地完成軟件項目工作所需的、最小的UML和建模技術(shù)子集。
b)類圖規(guī)定了代碼的結(jié)構(gòu)
c)時序圖將操作分配給類
三、設(shè)計模式的本質(zhì)論
a)模式是從解決具體問題抽象出來的,這種具體問題在特定的上下文中重復出現(xiàn)。也就是說,每個具體形式都對一種重復的問題采用重復的解決方案。
b)理解設(shè)計模式的結(jié)果和代價
i.對象過多:設(shè)計模式的精髓之一是將可變部分封裝為對象,帶來的好處是系統(tǒng)更加靈活,易于維護,但也大量增加了對象。如果不恰當?shù)厥褂迷O(shè)計模式,會使系統(tǒng)難以調(diào)試。
1.命令模式:將行為封裝為對象,這樣原來一個對象中的若干方法變成了若干命令對象。如果將命令模式應(yīng)用在一個GUI用戶界面上,每一個菜單項就要生成一個命令對象,原來由一個對象完成的工作現(xiàn)在可能需要十幾個對象來完成。
2.狀態(tài)模式:將不同的狀態(tài)封裝為對象,原來可能是通過判斷語句完成的工作分散到各個對象中完成。由于狀態(tài)是動態(tài)決定的,因此在設(shè)計測試用例時有難度。
ii.更復雜的裝配關(guān)系:很多設(shè)計模式依賴對象之間的關(guān)系,因此在初始化時需要執(zhí)行相應(yīng)的裝配工作,需要裝配對象的模式有如下幾種。
1.生成器模式:需要裝配生成器和導航器。
2.橋接模式:需要將代表邏輯的對象和代表實現(xiàn)的對象進行裝配。
3.觀察者模式:需要將不同的觀察者對象關(guān)聯(lián)在一起。
4.職責鏈模式:需要組裝整條職責鏈。
iii.測試難度加大:這是前面兩個結(jié)果導致的,由于對象的增多和對象間關(guān)系的復雜,因此測試用例的設(shè)計難度增大。特別是很多邏輯上的錯誤可能由裝配關(guān)系不當造成,并且在編譯時很難發(fā)現(xiàn)。解決測試難度大的方法是將測試用例文檔化,即繪制測試用例的對象圖。這個話題超出了本書的范圍,有興趣的讀者可參考相關(guān)書籍。
iv.程序結(jié)構(gòu)復雜:設(shè)計模式關(guān)注的是如何使軟件更具可維護性,因此從結(jié)構(gòu)上已經(jīng)與原始的需求完全不同。加上很多功能是通過對象的動態(tài)組合實現(xiàn)的,程序的動態(tài)結(jié)構(gòu)變得與靜態(tài)結(jié)構(gòu)同樣重要。從單純的靜態(tài)結(jié)構(gòu)(例如類圖)已經(jīng)很難理解實現(xiàn)的方式和最終的意圖了,這也是經(jīng)常是使用設(shè)計模式的代價之一。
c)設(shè)計模式不能做什么
i.設(shè)計模式不是法則
模式理論的精髓之一就是模式的使用是有前提和代價的,模式是在某種前提下,綜合各方面因素后考慮得出的結(jié)果。即在使用模式時總是要付出一定的代價,當然這種代價是可以接受的。如果某個模式在所有場合中的使用都是必然的,那么它就不能叫做模式了,而是一種必須遵守的法則。例如“面向接口,而非實現(xiàn)編程”,是法則而非模式。
ii.不能提高開發(fā)速度或者形象開發(fā)速度
如果以一個開發(fā)周期作為考核標準,恐怕沒有人會使用設(shè)計模式。設(shè)計模式并不能提高目前的開發(fā)速度,至少其關(guān)注的目標并不是開發(fā)速度。很多情況下甚至會降低開發(fā)速度,即使是正確地選擇了設(shè)計模式。
這是因為設(shè)計模式可能會引入更多的對象和更復雜的對象裝配關(guān)系,從而使得程序有更多的動態(tài)狀態(tài),從局部看來變得結(jié)構(gòu)復雜,難以理解并且測試困難。如果僅僅關(guān)注于形象進度,或者能夠百分之百地確定需求沒有變化,那么設(shè)計模式并不是很好的選擇。
iii.不是萬能的
設(shè)計模式的使用是自然而然的事情,很多情況下不使用設(shè)計模式是因為不需要,問題還沒有復雜到非用不可的程度。我們是為了設(shè)計而使用設(shè)計模式,而不是為了使用設(shè)計模式而設(shè)計。
當你的項目發(fā)現(xiàn)有如下問題之一時,就需要考慮重構(gòu)代碼,可能會有某種模式適合。
(1)代碼無法進行單元測試。
(2)需求的變動總是導致代碼的變動。
(3)有重復代碼存在。
(4)繼承層次過多。
(5)隱藏的依賴過多。
四、設(shè)計模式與架構(gòu)模式
a)主要架構(gòu)模式
i.流程處理模式
ii.客戶/服務(wù)器模式、
iii.模型—視圖—控制器模式(MVC)
iv.分層模式
b)確立軟件架構(gòu)考慮的因素
i.架構(gòu)中包的數(shù)量
ii.架構(gòu)中包之間的耦合度
iii.軟件元素的穩(wěn)定性軟件開發(fā)網(wǎng)
iv.軟件元素的分類
v.作為軟件系統(tǒng)運行環(huán)境的物理網(wǎng)絡(luò)拓樸
vi.軟件元素的安全、保密級別
vii.開發(fā)團隊的技術(shù)專長
viii.調(diào)整軟件架構(gòu),支持并行開發(fā)
看了這里之后才了解MVC模式與GOF那些設(shè)計模式有什么區(qū)別,
MVC模式屬于架構(gòu)模式,特別適合應(yīng)用于分布式應(yīng)用系統(tǒng)。
大型軟件的頂層架構(gòu)往往需要使用多種架構(gòu)樣式。如,整個目標軟件系統(tǒng)采用分層結(jié)構(gòu),在系統(tǒng)的不同層次內(nèi)再分別使用適宜的其他類型的架構(gòu)模式。