UML類圖
【矩形框】代表一個(gè)類(Class)。類圖分三層:
【線條】代表類之間的關(guān)系。 繼承:空心三角形+實(shí)線,鳥類繼承動(dòng)物類 實(shí)現(xiàn):空心三角形+虛線,鳥類實(shí)現(xiàn)飛翔接口 關(guān)聯(lián):實(shí)線箭頭,企鵝類知道氣候類(企鵝類中引用了氣候?qū)ο螅?/p> 聚合:空心菱形+實(shí)線箭頭,每只大雁都是屬于一個(gè)雁群,一個(gè)雁群可以有多只大雁(雁群中引用了大雁數(shù)組對(duì)象) 組合:實(shí)心菱形+實(shí)線箭頭,翅膀是鳥的一部分,擁有相同的生命周期(初始化鳥對(duì)象時(shí),同時(shí)實(shí)例化翅膀?qū)ο螅?/p> 依賴:虛線箭頭,動(dòng)物需要氧氣、水(氧氣和水是動(dòng)物類某個(gè)方法的參數(shù)) 六大原則 + 一個(gè)法則
1. 開放封閉原則開閉原則的意思是:對(duì)擴(kuò)展開放,對(duì)修改關(guān)閉。軟件實(shí)體(類、模塊、函數(shù)等)應(yīng)該可以擴(kuò)展,但不可修改。即面對(duì)需求,對(duì)程序的改動(dòng)是通過增加新代碼進(jìn)行的,而不是更改現(xiàn)有的代碼。 以計(jì)算器程序?yàn)槔?,抽象出一個(gè)運(yùn)算類,嗎,每當(dāng)要增加新的運(yùn)算方式時(shí),只要修改這個(gè)抽象類和增加新的運(yùn)算類,不會(huì)修改已有的運(yùn)算類。 2. 單一職責(zé)原則單一職責(zé)原則,就一個(gè)類而言,應(yīng)該僅有一個(gè)引起它變化的原因。 以俄羅斯方塊為例,窗體顯示(界面)是一個(gè)類,方塊的移動(dòng)控制(游戲邏輯)是另一個(gè)類,將不同的職責(zé)分離到不同的類上。 3. 里氏代換原則里氏替換原則:子類型必須能夠替換掉它們的父類型。(多態(tài)) 里氏代換原則是面向?qū)ο笤O(shè)計(jì)的基本原則之一。 里氏代換原則中說,任何基類可以出現(xiàn)的地方,子類一定可以出現(xiàn)。LSP 是繼承復(fù)用的基石,只有當(dāng)派生類可以替換掉基類,且軟件單位的功能不受到影響時(shí),基類才能真正被復(fù)用,而派生類也能夠在基類的基礎(chǔ)上增加新的行為。里氏代換原則是對(duì)開閉原則的補(bǔ)充。實(shí)現(xiàn)開閉原則的關(guān)鍵步驟就是抽象化,而基類與子類的繼承關(guān)系就是抽象化的具體實(shí)現(xiàn),所以里氏代換原則是對(duì)實(shí)現(xiàn)抽象化的具體步驟的規(guī)范。 4. 依賴倒轉(zhuǎn)原則也叫依賴倒置、依賴反轉(zhuǎn)。這個(gè)原則是開閉原則的基礎(chǔ)。 依賴倒轉(zhuǎn)原則,A)高層模塊不應(yīng)該依賴低層模塊,兩個(gè)都應(yīng)該依賴抽象;b)抽象不應(yīng)該依賴細(xì)節(jié),細(xì)節(jié)應(yīng)該依賴抽象。即針對(duì)接口名稱,不要對(duì)實(shí)現(xiàn)編程。 例如,電腦可以很容易修理,因?yàn)殡娔X內(nèi)部都是由一些(高內(nèi)聚低耦合的)配件組成,壞了換一個(gè)新的就可;但是收音機(jī)很難修理,因?yàn)槭找魴C(jī)里面都是一些元器件耦合在一起。 5. 接口隔離原則這個(gè)原則的意思是:使用多個(gè)隔離的接口,比使用單個(gè)接口要好。它還有另外一個(gè)意思是:降低類之間的耦合度。由此可見,其實(shí)設(shè)計(jì)模式就是從大型軟件架構(gòu)出發(fā)、便于升級(jí)和維護(hù)的軟件設(shè)計(jì)思想,它強(qiáng)調(diào)降低依賴,降低耦合。 6. 合成復(fù)用原則合成復(fù)用原則是指:盡量使用合成/聚合的方式,而不是使用繼承。 7. 迪米特法則又稱最少知道原則,是指:一個(gè)實(shí)體應(yīng)當(dāng)盡量少地與其他實(shí)體之間發(fā)生相互作用,使得系統(tǒng)功能模塊相對(duì)獨(dú)立。 如果兩個(gè)類不必彼此直接通信,那么這兩個(gè)類就不應(yīng)當(dāng)發(fā)生直接的相互作用。如果其中一個(gè)類需要調(diào)用另一個(gè)類的某一個(gè)方法,可以通過第三者轉(zhuǎn)發(fā)這個(gè)調(diào)用。 例如,公司小李去維修電腦,只需要去找IT部,讓IT部去找具體的人來維修電腦。 設(shè)計(jì)模式1. 簡(jiǎn)單工廠模式
傳入?yún)?shù),由工廠對(duì)象去實(shí)例化實(shí)際的操作對(duì)象。 以計(jì)算器為例,傳入操作運(yùn)算符( 2. 策略模式定義了算法家族,分別封裝起來,讓它們之間可以互相替換,此模式讓算法的變化,不會(huì)影響到使用算法的客戶(多態(tài))。 以超市打折為例,正常收費(fèi),打折收費(fèi)和返利收費(fèi)是具體策略,用一個(gè)類去管理具體策略;同時(shí)還可以與簡(jiǎn)單工廠模式結(jié)合,傳入算法名稱,由工廠去創(chuàng)建策略管理類。 【優(yōu)點(diǎn)】
3. 裝飾器模式裝飾器模式,動(dòng)態(tài)地給一個(gè)對(duì)象添加一些額外的職責(zé),就增加功能來說,裝飾器模式比生成子類更加靈活。它把每個(gè)要裝飾的功能放在單獨(dú)的類中,并讓這個(gè)類包裝它所要裝飾的對(duì)象,在使用時(shí)要注意裝飾的順序。 以穿衣服為例,人為一個(gè)抽象類,有穿衣這個(gè)抽象方法,具體的男人類繼承人抽象類,有一個(gè)抽象穿衣類(裝飾器類)繼承人抽象類,有具體的穿上衣類、穿外套類、穿內(nèi)褲類、穿外褲類繼承抽象穿衣類。先創(chuàng)建一個(gè)男人對(duì)象X、穿上衣對(duì)象A、穿內(nèi)褲對(duì)象B等,將X設(shè)置到A中,再將A設(shè)置到B中,鏈?zhǔn)秸{(diào)用(注意是一層套一層的)。 4. 代理模式代理模式,為其它對(duì)象提供一種代理以控制對(duì)這個(gè)對(duì)象的訪問。 例如,王小明通過戴勵(lì)給劉小紅送禮物,有 Subjec類:定義了RealSubject和Proxy的公用接口,這樣在任何使用RealSubject的地方都可以使用Proxy。【送禮物這一行為】 RealSubject類:定義Proxy所代表的真實(shí)實(shí)體。【王小明】 Proxy類:保存一個(gè)引用使得代理可以訪問真實(shí)實(shí)體,并提供一個(gè)與RealSubject內(nèi)相同的訪問方法,這樣代理就可以用來替代真實(shí)實(shí)體?!敬鲃?lì)】 5. 工廠方法模式工廠模式方法,定義一個(gè)用于創(chuàng)建對(duì)象對(duì)象的接口,讓子類決定實(shí)例化哪一個(gè)類,工廠方法使一個(gè)類的實(shí)例化延遲到其子類。 以計(jì)算器程序?yàn)槔瑒?chuàng)建一個(gè)工廠接口,然后加減乘除各建一個(gè)具體的工廠去實(shí)現(xiàn)這個(gè)接口,每個(gè)具體工廠負(fù)責(zé)創(chuàng)建具體的運(yùn)算對(duì)象。 6. 原型模式原型模式,用原型實(shí)例指定創(chuàng)建對(duì)象的種類,并通過拷貝這些原型對(duì)象創(chuàng)建新的對(duì)象。 例如,有一個(gè)抽象原型類有抽象clone方法,然后有多個(gè)具體原型類去實(shí)現(xiàn)該clone方法,注意【淺拷貝與深拷貝】,原型中引用的對(duì)象,拷貝的時(shí)候只會(huì)拷貝引用,需要在引用的對(duì)象中也實(shí)現(xiàn)拷貝方法,然后在給原型賦值的是對(duì)象的拷貝。 7. 模板方法模式定義一個(gè)操作中的算法的骨架,將一些步驟延遲到子類中。模板方法使得子類可以不改變一個(gè)算法的結(jié)構(gòu)即可重定義該算法的某些特定步驟。 比如,一個(gè)抽象動(dòng)物類有抽象吃食物的方法,在一些模板方法可以調(diào)用這個(gè)抽象方法(例如吃完東西才會(huì)睡覺),具體的狗類、貓類、鳥類實(shí)現(xiàn)具體的吃食物的方法。 8. 外觀模式外觀模式,為子系統(tǒng)中的一組接口提供一個(gè)一致的界面,此模式定義了一個(gè)高層接口,這個(gè)接口使得這一子系統(tǒng)更加容易使用。
例如股民炒股,股民需要知道多個(gè)股票的情況,耦合性過高,而把錢投在基金上,由基金來管理多支股票,用戶只用與基金打交道。 【何時(shí)使用】
9. 建造者模式建造者模式(Builder),又叫生成器模式,將一個(gè)復(fù)雜對(duì)象的構(gòu)建與它的表示分離,使得同樣的構(gòu)建過程可以創(chuàng)建不同的表示。 例如,一個(gè)畫小人程序,可以畫出瘦人、胖人等,有 Product類:小人類,由多個(gè)部分組成。 Builder接口:建造小人各個(gè)部分的抽象類。 ConcreteBuilder類:具體建造者,實(shí)現(xiàn)Builder接口。具體實(shí)現(xiàn)如何畫出小人的頭身手腳各個(gè)部分。 Director類:指揮者,構(gòu)建一個(gè)使用Builder接口的對(duì)象。用來根據(jù)用戶的需求構(gòu)建小人對(duì)象。 10. 觀察者模式觀察者模式,又叫發(fā)布-訂閱(Publish/Subscribe)模式,定義了一種一對(duì)多的依賴關(guān)系,讓多個(gè)觀察者對(duì)象同時(shí)監(jiān)聽某一個(gè)主題對(duì)象。這個(gè)主題對(duì)象在狀態(tài)發(fā)生變化時(shí),會(huì)通知所有觀察者對(duì)象,使它們能夠自動(dòng)更新自己。 例如,員工上班偷懶,需要前臺(tái)A或者前臺(tái)B望風(fēng),有 Subject類:抽象通知者類(主題)。一般用一個(gè)抽象類或者一個(gè)接口實(shí)現(xiàn)。它把所有對(duì)觀察者對(duì)象的引用保存在一個(gè)聚集里,每個(gè)主題都可以有任何數(shù)量的觀察者。抽象主題提供一個(gè)接口,可以增加和刪除觀察者對(duì)象。 Observer類:抽象觀察者,為所有的具體觀察者定義一個(gè)接口,在得到主題的通知時(shí)更新自己。這個(gè)接口叫做更新接口。抽象觀察者一般用一個(gè)抽象類或者一個(gè)接口實(shí)現(xiàn)。更新接口通常包含一個(gè)Update() 方法,這個(gè)方法叫做更新方法。 ConcreteSubject類:叫做具體主題或具體通知者,將有關(guān)狀態(tài)存入具體現(xiàn)察者對(duì)象;在具體主題的內(nèi)部狀態(tài)改變時(shí),給所有登記過的觀察者發(fā)出通知。具體主題角色通常用一個(gè)具體子類實(shí)現(xiàn)。 ConcreteObserver類:具體觀察者,實(shí)現(xiàn)抽象觀察者角色所要求的更新接口,以便使本身的狀態(tài)與主題的狀態(tài)相協(xié)調(diào)。具體觀察者角色可以保存一個(gè)指向具體主題對(duì)象的引用。具體觀察者角色通常用一個(gè)具體子類實(shí)現(xiàn)。
11. 抽象工廠模式抽象工廠模式(Abstract Factory),提供一個(gè)創(chuàng)建一系列相關(guān)或相互依賴對(duì)象的接口,而無需指定它們具體的類。解決涉及到多個(gè)產(chǎn)品系列的問題,有一個(gè)專門的工廠模式叫抽象工廠模式。 例如,有一個(gè)業(yè)務(wù)需要訪問指定的數(shù)據(jù)庫(可能會(huì)變動(dòng)),數(shù)據(jù)庫中又有幾張表,為了便于修改數(shù)據(jù)庫訪問方式,這時(shí)就需要使用抽象工廠模式。 抽象工廠接口:里面應(yīng)該包含所有的產(chǎn)品創(chuàng)建的抽象方法【創(chuàng)建數(shù)據(jù)庫的抽象方法】; 具體的工廠:實(shí)現(xiàn)抽象工廠接口,創(chuàng)建具有特定實(shí)現(xiàn)的產(chǎn)品對(duì)象【實(shí)例化對(duì)應(yīng)的具體數(shù)據(jù)庫對(duì)象】; 抽象產(chǎn)品:它們都有可能有多種不同的實(shí)現(xiàn)【數(shù)據(jù)庫的訪問資源方式的抽象方法】; 具體產(chǎn)品:繼承抽象產(chǎn)品,對(duì)抽象產(chǎn)品的具體分類的實(shí)現(xiàn)【具體數(shù)據(jù)庫的訪問資源方法】。 【改進(jìn)1】反射 Java反射:通過全限定類名去加載對(duì)應(yīng)類的字節(jié)碼(Class)文件
反射中的類名是字符串,可以采用變量,故更容易修改為不同的數(shù)據(jù)庫具體產(chǎn)品,且不用在主程序中寫switch方法。 使用DataAccess類,用反射技術(shù),取代IFactory、SqlserverFactory和AccessFactory。 【改進(jìn)2】反射 + 配置文件 將數(shù)據(jù)庫名稱放在配置文件中,這樣只需要修改配置文件就可以修改程序的訪問數(shù)據(jù)庫,不用去改程序代碼。 【總結(jié)】從這個(gè)角度上說,所有在用簡(jiǎn)單工廠的地方,都可以考慮用反射技術(shù)來去除switch或if,解除分支判斷帶來的耦合。 12. 狀態(tài)模式狀態(tài)模式(State),當(dāng)一個(gè)對(duì)象的內(nèi)在狀態(tài)改變時(shí)允許改變其行為,這個(gè)對(duì)象看起來像是改變了其類。 狀態(tài)模式主要解決的是當(dāng)控制一個(gè)對(duì)象狀態(tài)轉(zhuǎn)換的條件表達(dá)式過于復(fù)雜時(shí)的情況。把狀態(tài)的判斷邏輯轉(zhuǎn)移到表示不同狀態(tài)的一系列類當(dāng)中,可以把復(fù)雜的判斷邏輯簡(jiǎn)化。 比如,上班時(shí)不同時(shí)間做不同工作就可以使用狀態(tài)模式,首先有一個(gè)抽象狀態(tài)類,設(shè)置多個(gè)工作狀態(tài)繼承抽象狀態(tài)類,有一個(gè)工作類(上下文)來負(fù)責(zé)轉(zhuǎn)換工作轉(zhuǎn)態(tài),傳入任意一個(gè)工作狀態(tài),當(dāng)滿足某條件的時(shí)候,轉(zhuǎn)入下一工作狀態(tài)。 13. 適配器模式適配器模式(Adapter),將一個(gè)類的接口轉(zhuǎn)換成客戶希望的另外一個(gè)接口。Adapter模式使得原本由于接口不兼容而不能一起工作的那些類可以一起工作。 適配器模式有兩種類型,類適配器模式和對(duì)象適配器模式。類適配器通過多重繼承對(duì)一個(gè)接口與另一個(gè)接口進(jìn)行匹配。對(duì)象適配器模式主要結(jié)構(gòu)如下: Target:客戶期待的接口 Adaptee:需要適配的類 Adapter:實(shí)現(xiàn)Target接口,通過在內(nèi)部包裝一個(gè)Adaptee對(duì)象,把源接口轉(zhuǎn)換成目標(biāo)接口 14. 備忘錄模式備忘錄(Memento):在不破壞封裝性的前提下,捕獲一個(gè)對(duì)象的內(nèi)部狀態(tài),并在該對(duì)象之外保存這個(gè)狀態(tài)。這樣以后就可將該對(duì)象恢復(fù)到原先保存的狀態(tài)。 例如,有一個(gè)游戲角色,可以在戰(zhàn)斗之前保存狀態(tài),戰(zhàn)斗失敗了可以恢復(fù)到之前保存的狀態(tài)。有 Originator類:發(fā)起人(游戲角色)。負(fù)責(zé)創(chuàng)建一個(gè)備忘錄Memento,用以記錄當(dāng)前時(shí)刻它的內(nèi)部狀態(tài),并可使用備忘錄恢復(fù)內(nèi)部狀態(tài)。Originator 可根據(jù)需要決定Memento存儲(chǔ)Originator的哪些內(nèi)部狀態(tài)。 Memento類:備忘錄(角色狀態(tài))。負(fù)責(zé)存儲(chǔ)Originator對(duì)象的內(nèi)部狀態(tài),并可防止Originator 以外的其他對(duì)象訪問備忘錄Memento。備忘錄有兩個(gè)接口,Caretaker只能看到備忘錄的窄接口,它只能將備忘錄傳遞給其他對(duì)象。Originator能夠看到一個(gè)寬接口,允許它訪問返回到先前狀態(tài)所需的所有數(shù)據(jù)。 Caretaker類:管理者(負(fù)責(zé)管理狀態(tài))。負(fù)責(zé)保存好備忘錄Memento(Originator創(chuàng)建的備忘錄存在Caretaker里面),不能對(duì)備忘錄的內(nèi)容進(jìn)行操作或檢查。
15. 組合模式組合模式(Composite),將對(duì)象組合成樹形結(jié)構(gòu)以表示部分-整體的層次結(jié)構(gòu)。組合模式使得用戶對(duì)單個(gè)對(duì)象和組合對(duì)象的使用具有一致性。 比如,一個(gè)總公司有財(cái)務(wù)部、技術(shù)部、人力資源部等,還有分公司,分公司同樣有財(cái)務(wù)部、技術(shù)部、人力資源部等??梢韵仍O(shè)計(jì)一個(gè)公司的抽象類(或者接口),里面有增加、移除、顯示部門、履行職責(zé)的抽象方法,然后設(shè)計(jì)具體的公司類繼承該抽象類,實(shí)現(xiàn)這些方法,并加上children相關(guān)的方法;部門類也去繼承公司抽象類,實(shí)現(xiàn)這些方法。創(chuàng)建分公司的時(shí)候同創(chuàng)建總公司相同。 這樣,基本對(duì)象可以被組合為更復(fù)雜的組合對(duì)象,這個(gè)組合對(duì)象又可以被組合。 16. 迭代器模式迭代器模式(Iterator),提供一種方法順序訪問一個(gè)聚合對(duì)象中各個(gè)元素,而又不暴露該對(duì)象的內(nèi)部表示。 當(dāng)你需要訪問一個(gè)聚集對(duì)象,而且不管這些對(duì)象是什么都需要遍歷的時(shí)候,你就應(yīng)該考慮用迭代器模式。當(dāng)你需要對(duì)聚集有多種方式遍歷時(shí),可以考慮用迭代器模式。Java中的 迭代器模式就是分離了集合對(duì)象的遍歷行為,抽象出一個(gè)選代器類來負(fù)責(zé),這樣既可以做到不暴露集合的內(nèi)部結(jié)構(gòu),又可讓外部代碼透明地訪問集合內(nèi)部的數(shù)據(jù)。迭代器模式在訪問數(shù)組、集合、列表等數(shù)據(jù)時(shí),尤其是數(shù)據(jù)庫數(shù)據(jù)操作時(shí),是非常普遍的應(yīng)用,但由于它太普遍了,所以各種高級(jí)語言都對(duì)它進(jìn)行了封裝。 17. 單例模式單例模式(Singleton),保證一個(gè)類僅有一個(gè)實(shí)例,并提供一個(gè)訪問它的全局訪問點(diǎn)。 讓類自身負(fù)責(zé)保存它的唯一實(shí)例。這個(gè)類可以保證沒有其他實(shí)例可以被創(chuàng)建,并且它可以提供一個(gè)訪問該實(shí)例的方法(靜態(tài)方法)。
一般采用餓漢式在類直接創(chuàng)建靜態(tài)對(duì)象:
如果明確需要使用懶加載,可以采用登記式/靜態(tài)內(nèi)部類方式:
否則使用雙檢鎖/雙重校驗(yàn)鎖方式:
18. 橋接模式橋接模式(Bridge),將抽象部分與它的實(shí)現(xiàn)部分分離,使它們都可以獨(dú)立地變化。(實(shí)現(xiàn)指的是抽象類和它的派生類用來實(shí)現(xiàn)自己的對(duì)象)。 實(shí)現(xiàn)系統(tǒng)可能有多角度分類,每一種分類都有可能變化,那么就把這種多角度分離出來讓它們獨(dú)立變化,減少它們之間的耦合。 例如為不同的手機(jī)開發(fā)游戲,可以將手機(jī)硬件和軟件分離,手機(jī)有A、B兩個(gè)品牌,軟件有M、N兩類。有一個(gè)抽象手機(jī)類,A手機(jī)、B手機(jī)繼承抽象手機(jī)類;有一個(gè)抽象軟件類,M軟件、N軟件繼承抽象軟件類;然后抽象手機(jī)類引用抽象軟件類。這樣不管增加手機(jī)還是增加軟件都很方便。
19. 命令模式命令模式(Command),將一個(gè)請(qǐng)求封裝為一個(gè)對(duì)象,從而使你可用不同的請(qǐng)求對(duì)客戶進(jìn)行參數(shù)化;對(duì)請(qǐng)求排隊(duì)或記錄請(qǐng)求日志,以及支持可撤銷的操作。 例如點(diǎn)燒烤,我們是客戶端,服務(wù)員是Invoker,向廚師Receiver發(fā)送命令,其中有一個(gè)抽象的Command類用于聲明執(zhí)行操作的接口,ConcreteCommand類繼承Command類,(綁定接收者廚師Receiver)用于實(shí)現(xiàn)具體的動(dòng)作。服務(wù)員Invoke是通過Command類來向廚師Receiver進(jìn)行交互的。 【優(yōu)點(diǎn)】
20. 職責(zé)鏈模式職責(zé)鏈模式(Chain of Responsibility),使多個(gè)對(duì)象都有機(jī)會(huì)處理請(qǐng)求,從而避免請(qǐng)求的發(fā)送者和接收者之間的耦合關(guān)系。將這個(gè)對(duì)象連成一條鏈,并沿著這條鏈傳遞該請(qǐng)求,直到有一個(gè)對(duì)象處理它為止。 比如,員工請(qǐng)假,不同管理者級(jí)別能處理的請(qǐng)假天數(shù)不一樣。設(shè)置一個(gè)管理者抽象類,有設(shè)置上級(jí)(繼任者)方法和處理請(qǐng)求的抽象方法,有多個(gè)級(jí)別的管理者繼承該抽象類,實(shí)現(xiàn)處理請(qǐng)求的抽象方法。這樣,員工(客戶端)每次都是向組長(zhǎng)請(qǐng)假,組長(zhǎng)批不了的就交由部門經(jīng)理處理,經(jīng)理處理不了的就由總監(jiān)處理。 21. 中介者模式中介者模式(Mediator),用一個(gè)中介對(duì)象來封裝一系列的對(duì)象交互。中介者使各對(duì)象不需要顯式地相互引用,從而使其耦合松散,而且可以獨(dú)立地改變它們之間的交互。 例如,聯(lián)合國(guó)安理會(huì)調(diào)節(jié)國(guó)家沖突。有一個(gè)聯(lián)合國(guó)抽象類,里面有調(diào)節(jié)抽象方法(參數(shù)為調(diào)節(jié)信息和調(diào)節(jié)對(duì)象),有具體的安理會(huì)繼承聯(lián)合國(guó)抽象類,實(shí)現(xiàn)具體方法;有國(guó)家抽象類,需要設(shè)置中介者,有具體國(guó)家類繼承國(guó)家抽象類,實(shí)現(xiàn)具體方法;在實(shí)際使用時(shí),由中介者去調(diào)用國(guó)家類的方法。 中介者模式一般應(yīng)用于一組對(duì)象以定義良好但是復(fù)雜的方式進(jìn)行通信的場(chǎng)合,比如剛才得到的窗體Form對(duì)象或Web頁面aspx,以及想定制一個(gè)分布在多個(gè)類中的行為,而又不想生成太多的子類的場(chǎng)合。 【優(yōu)點(diǎn)】
【缺點(diǎn)】
22. 享元模式享元模式(Flyweight),運(yùn)用共享技術(shù)有效地支持大量細(xì)粒度的對(duì)象。 比如為不同人創(chuàng)建類似的網(wǎng)站,可以把網(wǎng)站的公共部分抽取出來,將用戶設(shè)置為外部狀態(tài)傳進(jìn)去。這樣的話,就算要為10個(gè)用戶創(chuàng)建網(wǎng)站,也可以只有一個(gè)網(wǎng)站實(shí)例。有用戶類,有一個(gè)抽象網(wǎng)站類,里面有抽象使用方法(傳入用戶),有多個(gè)具體的網(wǎng)站類,實(shí)現(xiàn)抽象方法;有一個(gè)網(wǎng)站工廠負(fù)責(zé)管理網(wǎng)站(沒有則創(chuàng)建,有則取出返回)。 如果一個(gè)應(yīng)用程序使用了大量的對(duì)象,而大量的這些對(duì)象造成了很大的存儲(chǔ)開銷時(shí)就應(yīng)該考慮使用;還有就是對(duì)象的大多數(shù)狀態(tài)可以外部狀態(tài),如果刪除對(duì)象的外部狀態(tài),那么可以用相對(duì)較少的共享對(duì)象取代很多組對(duì)象,此時(shí)可以考慮使用享元模式。 【優(yōu)點(diǎn)】
【缺點(diǎn)】
23. 解釋器模式解釋器模式(interpreter),給定一個(gè)語言,定義它的文法的一種表示,并定義一個(gè)解釋器,這個(gè)解釋器使用該表示來解釋語言中的句子。 比如正則表達(dá)式,可以用特定的文法去匹配字符串。 AbstractExpression類:抽象表達(dá)式。聲明一個(gè)抽象的解釋操作,這個(gè)接口為抽象語法樹中所有的節(jié)點(diǎn)所共享。 TerminalExpression類:終結(jié)符表達(dá)式。實(shí)現(xiàn)與文法中的終結(jié)符相關(guān)聯(lián)的解釋操作。實(shí)現(xiàn)抽象表達(dá)式中所要求的接口,主要是一個(gè)interpret() 方法。文法中每一個(gè)終結(jié)符都有一個(gè)具體終結(jié)表達(dá)式與之相對(duì)應(yīng)。 NonterminalExpression類:非終結(jié)符表達(dá)式,為文法中的非終結(jié)符實(shí)現(xiàn)解釋操作。對(duì)文法中每一條規(guī)則 R1、R2……Rn 都需要一個(gè)具體的非終結(jié)符表達(dá)式類。通過實(shí)現(xiàn)抽象表達(dá)式的interpret() 方法實(shí)現(xiàn)解釋操作。解釋操作以遞歸方式調(diào)用上面所提到的代表R1、R2……Rn中各個(gè)符號(hào)的實(shí)例變量。 Context類:包含解釋器之外的一些全局信息。 24. 訪問者模式訪問者模式(Visitor),表示一個(gè)作用于某對(duì)象結(jié)構(gòu)中的各元素的操作。它使你可以在不改變各元素的類的前提下定義作用于這些元素的新操作。 比如,有男人、女人2種數(shù)據(jù)結(jié)構(gòu),每類人都有多個(gè)情緒,情緒對(duì)應(yīng)的操作不同。有抽象訪問者類Visitor,為該對(duì)象結(jié)構(gòu)中ConcreteElement的每一個(gè)類聲明一個(gè)Visit操作;ConcreteVisitor1和ConcreteVisitor2類,具體訪問者,實(shí)現(xiàn)每個(gè)由Visitor聲明的操作;人抽象類Element,定義一個(gè)Accept操作,它以一個(gè)訪問者為參數(shù);男人類 ConcreteElementA和女人類ConcreteElementB,具體元素,實(shí)現(xiàn)Accept操作;人的集合ObjectStructure類,能枚舉它的元素,可以提供一個(gè)高層的接口以允許訪問者訪問它的元素。
訪問者模式適用于數(shù)據(jù)結(jié)構(gòu)相對(duì)穩(wěn)定的系統(tǒng),它把數(shù)據(jù)結(jié)構(gòu)和作用于結(jié)構(gòu)上的操作之間的耦合解脫開,使得操作集合可以相對(duì)自由地演化。 【優(yōu)點(diǎn)】
【缺點(diǎn)】
設(shè)計(jì)模式總結(jié)[23種]1. 創(chuàng)建型模式
抽象工廠模式:提供一個(gè)創(chuàng)建一系列或相關(guān)依賴對(duì)象的接口,而無需指定它們具體的類。 建造者模式:將一個(gè)復(fù)雜對(duì)象的構(gòu)建與它的表示分離,使得同樣的構(gòu)建過程可以創(chuàng)建不同的表示。 工廠方法模式:定義一個(gè)用于創(chuàng)建對(duì)象的接口,讓子類決定實(shí)例化哪一個(gè)類,工廠模式使一個(gè)類的實(shí)例化延遲到其子類。 原型模式:用原型實(shí)例指定創(chuàng)建對(duì)象的種類,并且通過拷貝這些原型創(chuàng)建新的對(duì)象。 單例模式:保證一個(gè)類僅有一個(gè)實(shí)例,并提供一個(gè)訪問它的全局訪問點(diǎn)。
2. 結(jié)構(gòu)型模式
適配器模式:將一個(gè)類的接口轉(zhuǎn)換成客戶希望的另外一個(gè)接口。適配器模式使得原本由于接口不兼容而不能一起工作的那些類可以一起工作。 橋接模式:將抽象部分與它的實(shí)現(xiàn)部分分離,使它們都可以獨(dú)立地變化。 組合模式:將對(duì)象組合成樹形結(jié)構(gòu)以表示“部分-整體”的層次結(jié)構(gòu),組合模式使得用戶對(duì)單個(gè)對(duì)象和組合對(duì)象的使用具有一致性。 裝飾器模式:動(dòng)態(tài)地給一個(gè)對(duì)象添加一些額外的職責(zé)。就增加功能來說,裝飾模式相比生成子類更加靈活。 外觀模式:為子系統(tǒng)中的一組接口提供一個(gè)一致的界面,外觀模式定義了一個(gè)高層接口,這個(gè)接口使得這一子系統(tǒng)更加容易使用。 享元模式:運(yùn)用共享技術(shù)有效地支持大量細(xì)粒度的對(duì)象。 代理模式:為其他對(duì)象提供一種代理以控制對(duì)這個(gè)對(duì)象的訪問。 3. 行為型模式
觀察者模式:定義對(duì)象間的一種一對(duì)多的依賴關(guān)系,當(dāng)一個(gè)對(duì)象的狀態(tài)發(fā)生改變時(shí),所有依賴于它的對(duì)象都得到通知并被自動(dòng)更新。 模板方法模式:定義一個(gè)操作的算法骨架,而將一些步驟延遲到子類中,模板方法使得子類可以不改變一個(gè)算法的結(jié)構(gòu)即可重定義該算法的某些特定步驟。 命令模式:將一個(gè)請(qǐng)求封裝為一個(gè)對(duì)象,從而使你可用不同的請(qǐng)求對(duì)客戶進(jìn)行參數(shù)化;可以對(duì)請(qǐng)求排隊(duì)或記錄請(qǐng)求日志,以及支持可撤銷的操作。 狀態(tài)模式:允許一個(gè)對(duì)象在其內(nèi)部狀態(tài)改變時(shí)改變它的行為,讓對(duì)象看起來似乎修改了它的類。 職責(zé)鏈模式:多個(gè)對(duì)象都有機(jī)會(huì)處理請(qǐng)求,從而避免請(qǐng)求的發(fā)送者和接收者之間的耦合關(guān)系。將這些對(duì)象連成一條鏈,并沿著這條鏈傳遞該請(qǐng)求,直到有一個(gè)對(duì)象處理它為止。 解釋器模式:給定一個(gè)語言,定義它的文法的一種表示,并定義一個(gè)解釋器,這個(gè)解釋器使用該表示來解釋語言中的句子。 中介者模式:一個(gè)中介對(duì)象來封裝一系列的對(duì)象交互。中介者使各對(duì)像不需要顯式地相互引用,從而使其耦合松散,而且可以獨(dú)立地改變它們之間的交互。 訪問者模式:表示一個(gè)作用于某對(duì)象結(jié)構(gòu)中的各元素的操作。它使你可以在不改變各元素的類的前提下定義作用于這些元素的新操作。 策略模式:定義一系列的算法,把它們一個(gè)個(gè)封裝起來,并且使它們可相互替換,使得算法可獨(dú)立于使用它的客戶而變化。 備忘錄模式:在不破壞封裝性的前提下,捕獲一個(gè)對(duì)象的內(nèi)部狀態(tài),并在該對(duì)象之外保存這個(gè)狀態(tài)。這樣以后就可將該對(duì)象恢復(fù)到原先保存的狀態(tài)。 迭代器模式:提供一種方法順序訪問一個(gè)聚合對(duì)象中各個(gè)元素,而又不需暴露該對(duì)象的內(nèi)部表示。 |
|
|