|
每一個(gè)模式描述了一個(gè)在我們周圍不斷重復(fù)發(fā)生的問題,以及該問題的解決方案的核心
——Christopher Alexander
設(shè)計(jì)模式描述了軟件設(shè)計(jì)過程中某一類常見問題的一般性的解決方案。面向?qū)ο笤O(shè)計(jì)模式描述了面向?qū)ο笤O(shè)計(jì)過程中、特定場(chǎng)景下、類與相互通信的對(duì)象之間常見的組織關(guān)系。人是一個(gè)經(jīng)驗(yàn)性的動(dòng)物
GoF 23種設(shè)計(jì)模式
歷史性著作《設(shè)計(jì)模式:可復(fù)用面向?qū)ο筌浖幕A(chǔ)》一書中描述了23種經(jīng)典面向?qū)ο笤O(shè)計(jì)模式,創(chuàng)立了模式在軟件設(shè)計(jì)中的地位。該書四位作者被人們并成為Gang of Four(GoF),“四人組”,該書描述的23種經(jīng)典設(shè)計(jì)模式又被人們稱為GoF23種設(shè)計(jì)模式。
由于《設(shè)計(jì)模式:可復(fù)用面向?qū)ο筌浖幕A(chǔ)》一書確定了設(shè)計(jì)模式的地位,人們通常所說的設(shè)計(jì)模式隱含地表示“面向?qū)ο笤O(shè)計(jì)模式”。但這并不意味“設(shè)計(jì)模式”就等于“面向?qū)ο笤O(shè)計(jì)模式”。除了“面向?qū)ο笤O(shè)計(jì)模式”外,還有其他設(shè)計(jì)模式。除了GoF23中設(shè)計(jì)模式外,還有更多的面向?qū)ο笤O(shè)計(jì)模式。
GoF23種設(shè)計(jì)模式是學(xué)習(xí)面向?qū)ο笤O(shè)計(jì)模式的起點(diǎn),而非終點(diǎn);本課程的目標(biāo)是讓大家在建立在有效方法的基礎(chǔ)上,掌握GoF23種設(shè)計(jì)模式。
設(shè)計(jì)模式與面向?qū)ο?/strong>
面向?qū)ο笤O(shè)計(jì)模式解決的是“類與相互通信的對(duì)象之間的組織關(guān)系”,包括它們的角色、職責(zé)、協(xié)作方式幾個(gè)方面。面向?qū)ο笤O(shè)計(jì)模式是“好的面向?qū)ο笤O(shè)計(jì)”,所謂“好的面向?qū)ο笤O(shè)計(jì)”是那些可以滿足“應(yīng)對(duì)變化,提高服用”的設(shè)計(jì)。面向?qū)ο笤O(shè)計(jì)模式描述的是軟件設(shè)計(jì),因此它是獨(dú)立于編程語言的,但是面向?qū)ο笤O(shè)計(jì)模式的最終實(shí)現(xiàn)仍然要使用面向?qū)ο缶幊陶Z言來表達(dá),本課程基于C#語言,但實(shí)際上它適用于支持.NET框架的所有.NET語言,如Visual Basic.NET、C++/CLI等。
面向?qū)ο笤O(shè)計(jì)模式不像算法技巧,可以照搬照用,它是建立在對(duì)“面向?qū)ο?rdquo;純熟、深入的理解的基礎(chǔ)上的經(jīng)驗(yàn)性知識(shí)。掌握面向?qū)ο笤O(shè)計(jì)模式的前提是首先掌握“面向?qū)ο?rdquo;!
從編程語言直觀了解面向?qū)ο?/strong>
各種面向?qū)ο缶幊陶Z言相互有別,但都能看到它們對(duì)面向?qū)ο笕髾C(jī)制的支持,即:“封裝、繼承、多態(tài)”
-封裝,隱藏內(nèi)部實(shí)現(xiàn)
-繼承,復(fù)用現(xiàn)有代碼
-多態(tài),改寫對(duì)象行為
使用面向?qū)ο缶幊陶Z言(如C#),可以推動(dòng)程序員以面向?qū)ο蟮乃季S來思考軟件設(shè)計(jì)結(jié)構(gòu),從而強(qiáng)化面向?qū)ο蟮木幊谭妒健#是一門支持面向?qū)ο缶幊痰膬?yōu)秀語言,包括:各種級(jí)別的封裝支持;單實(shí)現(xiàn)繼承+多接口實(shí)現(xiàn);抽象方法與虛方法重寫。
但OOPL并非面向?qū)ο蟮娜?/strong>
通過面向?qū)ο缶幊陶Z言(OOPL)認(rèn)識(shí)到的面向?qū)ο螅⒉皇敲嫦驅(qū)ο蟮娜?,甚至只是淺陋的面向?qū)ο蟆OPL的三大機(jī)制“封裝、繼承、多態(tài)”可以表達(dá)面向?qū)ο蟮乃懈拍?,但這三大機(jī)制本身并沒有刻畫出面向?qū)ο蟮暮诵木?。換言之,既可以用這三大機(jī)制做出“好的面向?qū)ο笤O(shè)計(jì)”,也可以用這三大機(jī)制做出“差的面向?qū)ο笤O(shè)計(jì)”。不是使用了面向?qū)ο蟮恼Z言(例如C#),就實(shí)現(xiàn)了面向?qū)ο蟮脑O(shè)計(jì)與開發(fā)!因此我們不能依賴編程語言的面向?qū)ο髾C(jī)制,來掌握面向?qū)ο蟆?/p>
OOPL沒有回答面向?qū)ο蟮母拘詥栴}——我們?yōu)槭裁匆褂妹嫦驅(qū)ο??我們?yīng)該怎樣使用三大機(jī)制來實(shí)現(xiàn)“好的面向?qū)ο?rdquo;?我們應(yīng)該遵循什么樣的面向?qū)ο笤瓌t?任何一個(gè)嚴(yán)肅的面向?qū)ο蟪绦騿T(例如C#程序員),都需要系統(tǒng)地學(xué)習(xí)面向?qū)ο蟮闹R(shí),單純從編程語言上獲得的面向?qū)ο笾R(shí),不能夠勝任面向?qū)ο笤O(shè)計(jì)與開發(fā)。
從一個(gè)示例談起
重新認(rèn)識(shí)面向?qū)ο?/strong>
對(duì)于前面的例子,從宏觀層面來看,面向?qū)ο蟮臉?gòu)建方式更能適應(yīng)軟件的變化,能將變化所帶來的影響減為最小。從微觀層面來看,面向?qū)ο蟮姆绞礁鼜?qiáng)調(diào)各個(gè)類的“責(zé)任”,新增員工類型不會(huì)影響原來員工類型的實(shí)現(xiàn)代碼——這更符合真實(shí)的世界,也更能控制變化所影響的范圍,畢竟Engineer類不應(yīng)該為新增的“鐘點(diǎn)工”來買單……
對(duì)象是什么?
-從概念層面講,對(duì)象是某種擁有責(zé)任的抽象。
-從規(guī)格層面講,對(duì)象是一系列可以被其他對(duì)象使用的公共接口。
-從語言實(shí)現(xiàn)層面來看,對(duì)象封裝了代碼和數(shù)據(jù)。
有了這些認(rèn)識(shí)之后,怎樣才能設(shè)計(jì)“好的面向?qū)ο?rdquo;?
-遵循一定的面向?qū)ο笤O(shè)計(jì)原則
-熟悉一些典型的面向?qū)ο笤O(shè)計(jì)模式
從設(shè)計(jì)原則到設(shè)計(jì)模式
針對(duì)接口編程,而不是針對(duì)實(shí)現(xiàn)編程:客戶無需知道所使用對(duì)象的特定類型,只需要知道對(duì)象擁有客戶所期望的接口
優(yōu)先使用對(duì)象組合,而不是類繼承:類繼承通常為“白箱復(fù)用”,對(duì)象組合通常為“黑箱復(fù)用”。繼承在某種成都上破壞了封裝性,子類父類耦合度高;而對(duì)象組合則只要求被組合的對(duì)象具有良好定義的接口,耦合度低。
封裝變化點(diǎn)
-使用封裝來創(chuàng)建對(duì)象之間的分界層,讓設(shè)計(jì)者可以在分界層的一側(cè)進(jìn)行修改,而不會(huì)對(duì)另一側(cè)產(chǎn)生不良的影響,從而實(shí)現(xiàn)層次間的松耦合。使用重構(gòu)得到模式——設(shè)計(jì)模式的應(yīng)用不宜先入為主,一上來就使用設(shè)計(jì)模式是對(duì)設(shè)計(jì)模式的最大誤用。沒有一步到位的設(shè)計(jì)模式。敏捷軟件開發(fā)實(shí)踐提倡的“Refactoring to Patterns”是目前普遍公認(rèn)的最好的使用設(shè)計(jì)模式的方法。
幾條更具體的設(shè)計(jì)原則
單一職責(zé)原則(SRP)
-一個(gè)類應(yīng)該僅有一個(gè)引起它變化的原因。
開放封閉原則(OCP)
-類模塊應(yīng)該是可擴(kuò)展的,但是不可修改(對(duì)擴(kuò)展開放,對(duì)更改封閉)
Liskov替換原則(LSP)
-子類必須能夠替換它們的基類
依賴倒置原則(DIP)
-高層模塊不應(yīng)該依賴于低層模塊,二者都應(yīng)該依賴于抽象。
-抽象不應(yīng)該依賴于實(shí)現(xiàn)細(xì)節(jié),實(shí)現(xiàn)細(xì)節(jié)應(yīng)該依賴于抽象。
接口隔離原則(ISP)
-不應(yīng)該強(qiáng)迫客戶程序依賴于它們不用的方法。
總結(jié)
設(shè)計(jì)模式描述了軟件設(shè)計(jì)過程中某一類常見問題的一般性的解決方案。面向?qū)ο笤O(shè)計(jì)模式描述了面向?qū)ο笤O(shè)計(jì)過程中、特定場(chǎng)景下、類與相互通信的對(duì)象之間常見的組織關(guān)系。深刻理解面向?qū)ο笫菍W(xué)好設(shè)計(jì)模式的基礎(chǔ),掌握一定的面向?qū)ο笤O(shè)計(jì)原則才能把握面向?qū)ο笤O(shè)計(jì)模式的精髓,從而實(shí)現(xiàn)靈活運(yùn)用設(shè)計(jì)模式。
三大基本面向?qū)ο笤O(shè)計(jì)原則
-針對(duì)接口編程,而不是針對(duì)實(shí)現(xiàn)編程
-優(yōu)先使用對(duì)象組合,而不是類繼承
-封裝變化點(diǎn)
使用重構(gòu)得到模式。敏捷軟件開發(fā)實(shí)踐提倡的“Refactoring to Patterns”是目前普遍公認(rèn)的最好的使用設(shè)計(jì)模式的方法。
it知識(shí)庫:C#面向?qū)ο笤O(shè)計(jì)模式縱橫談:面向?qū)ο笤O(shè)計(jì)模式與原則,轉(zhuǎn)載需保留來源!
鄭重聲明:本文版權(quán)歸原作者所有,轉(zhuǎn)載文章僅為傳播更多信息之目的,如作者信息標(biāo)記有誤,請(qǐng)第一時(shí)間聯(lián)系我們修改或刪除,多謝。