2018-03-28

Boolan C++設(shè)計(jì)模式三

對象性能”模式:面向?qū)ο蠛芎玫慕鉀Q了“抽象”的問題,但是必不可免地要付出一定的代價(jià)眼五。對于通常情況來講氧敢,面向?qū)ο蟮某杀敬蠖伎梢院雎圆挥?jì)。但是某些情況殷蛇,面向?qū)ο笏鶐淼某杀颈仨氈?jǐn)慎處理。

?典型模式 :Sington :Flyweight

單例模式Singleton:

定義:保證一個類僅有一個實(shí)例橄浓,并提供一個該實(shí)例的全局訪問點(diǎn)粒梦。 ——《設(shè)計(jì)模式》GoF

動機(jī):在軟件系統(tǒng)中,經(jīng)常有這樣一個特殊的類荸实,必須保證它們在系統(tǒng)中只存在一個示例匀们,才能確保他們的邏輯正確性、以及良好的效率准给。 這個應(yīng)該類設(shè)計(jì)者的責(zé)任泄朴,而不是使用者的責(zé)任。

要點(diǎn)總結(jié) :

?Singleton模式中的實(shí)力構(gòu)造器可以設(shè)置為protected露氮,以允許子類派生

??Singleton模式一般不要支持拷貝構(gòu)造函數(shù)和Clone接口祖灰,因?yàn)橛锌赡軙?dǎo)致多個對象實(shí)例,與Singleton模式的初衷相違背畔规。

??如何實(shí)現(xiàn)多線程環(huán)境下安全的Singleton夫植?注意對雙檢查鎖的正確實(shí)現(xiàn)。

享元模式flyweight:

定義:運(yùn)用共享技術(shù)有效地支持大量的細(xì)粒度對象

動機(jī):在軟件系統(tǒng)采用純粹對象方案的問題在于大量細(xì)粒度的對象會很快充斥在系統(tǒng)中油讯,從而帶來很高的運(yùn)行是代價(jià)——主要指內(nèi)存需求方面的代價(jià)延欠。

要點(diǎn)總結(jié) :

?面向?qū)ο蠛芎玫慕鉀Q了抽相性的問題,但是作為一個運(yùn)行在機(jī)器中的程序?qū)嶓w由捎,我們需要考慮對象的代價(jià)問題。Flyweight主要解決面向的代價(jià)問題,一般不觸及面向?qū)ο蟮某橄笮詥栴}软驰。

??Flyweight采用對象共享的做法來降低系統(tǒng)中的對象的個數(shù),從而降低細(xì)粒度對象給系統(tǒng)帶來的內(nèi)存壓力锭亏。在具體實(shí)現(xiàn)方面纠吴,要注意對像狀態(tài)的處理。

?對象的數(shù)量太大慧瘤,從而導(dǎo)致對像內(nèi)存開銷加大——什么樣的數(shù)量才算大戴已?這需要我們仔細(xì)根據(jù)具體應(yīng)用情況進(jìn)行評估,而不能憑空臆斷锅减。

“狀態(tài)變化”模式 :在組建構(gòu)建過程中糖儡,某些對象的狀態(tài)經(jīng)常面臨變化,如何對這些變化進(jìn)行有效的管理怔匣?同時又維持高層模塊的穩(wěn)定握联?“狀態(tài)變化”模式為這一個問題提供了一種解決方案。

典型模式 :State 每瞒、Memento

狀態(tài)模式State:

定義:?允許一個對象在其內(nèi)部狀態(tài)改變是改變它的行為金闽。從而使對像看起來似乎修改其行為。

動機(jī): 在軟件構(gòu)建過程中独泞,某些對象的狀態(tài)如果改變呐矾,其行為也會隨之而發(fā)生變化,比如文檔處于只讀狀態(tài)懦砂,其支持的行為和讀寫狀態(tài)支持的行為就可能會完全不同蜒犯。

要點(diǎn)總結(jié):

??State模式將所有與一個特定狀態(tài)相關(guān)的行為都放入一個State的子類對象中,在對像狀態(tài)切換時荞膘, 切換相應(yīng)的對象罚随;但同時維持State的接口,這樣實(shí)現(xiàn)了具體操作與狀態(tài)轉(zhuǎn)換之間的解耦羽资。

?為不同的狀態(tài)引入不同的對象使得狀態(tài)轉(zhuǎn)換變得更加明確淘菩,而且可以保證不會出現(xiàn)狀態(tài)不一致的情況,因?yàn)檗D(zhuǎn)換是原子性的——即要么徹底轉(zhuǎn)換過來屠升,要么不轉(zhuǎn)換潮改。

?如果State對象沒有實(shí)例變量,那么各個上下文可以共享同一個State對象腹暖,從而節(jié)省對象開銷汇在。


備忘錄Memento:

定義:在不破壞封裝性的前提下,不活一個對象的內(nèi)部狀態(tài)脏答,并在該對像之外保存這個狀態(tài)糕殉。這樣以后就可以將該對像恢復(fù)到原想保存的狀態(tài)。

動機(jī):在軟件構(gòu)建過程中阿蝶,某些對象的狀態(tài)在轉(zhuǎn)會過程中羡洁,可能由于某種需求,要求程序能夠回溯到對像之前處于某個點(diǎn)時的狀態(tài)冶匹。如果使用一些公有借口來讓其它對象得到對象的狀態(tài)嚼隘,便會暴露對象的實(shí)現(xiàn)細(xì)節(jié)袒餐。

要點(diǎn)總結(jié):

?備忘錄(Memento)存儲原發(fā)器(Originator)對象的內(nèi)部狀態(tài)灸眼,在需要時恢復(fù)原發(fā)器的狀態(tài)。

??Memento模式的核心是信息隱藏霉囚,即Originator需要向外接隱藏信息盈罐,保持其封裝性闪唆。但同時又需要將其狀態(tài)保持到外界(Memento)

?由于現(xiàn)代語言運(yùn)行時(如C#悄蕾、java等)都具有相當(dāng)?shù)膶ο笮蛄谢С郑虼送捎眯瘦^高奠骄、有較容易正確實(shí)現(xiàn)的序列化方案來實(shí)現(xiàn)Memento模式含鳞。 由于《設(shè)計(jì)模式》是在94年定義的民晒,現(xiàn)在很多的技術(shù)發(fā)展已經(jīng)變化锄禽,現(xiàn)在Memento的實(shí)現(xiàn)方法已經(jīng)過時了,現(xiàn)在在使用其他的方式在做這件事磁滚,但是對于思想并沒有發(fā)生變化垂攘。在備份的過程中淤刃,還需要保持封裝的時候逸贾,將信息保存到外部。

“數(shù)據(jù)結(jié)構(gòu)”模式 :常常有一些組建在內(nèi)部具有特定的數(shù)據(jù)結(jié)構(gòu)灼伤,如果讓客戶程序依賴這些特定的數(shù)據(jù)結(jié)構(gòu)狐赡,將極大的破壞組件的復(fù)用颖侄。這時候隆敢,將這些數(shù)據(jù)結(jié)構(gòu)封裝在內(nèi)部拂蝎,在外部提供統(tǒng)一的接口,來實(shí)現(xiàn)與特定數(shù)據(jù)結(jié)構(gòu)無關(guān)的訪問玄货,是一種行之有效的解決方案松捉。

典型模式 :Composite 馆里、Iterator 、Chain of Responsibility

組合模式Composite:

定義:?將對象組合成樹形結(jié)構(gòu)以表示“部分-整體”的層級結(jié)構(gòu)丙者。Compisite使得用戶對單個對象和組合對象的使用具有一致性(穩(wěn)定)械媒。

動機(jī):在某些軟件情況下,客戶代碼過多地依賴于對像容器復(fù)雜的內(nèi)部實(shí)現(xiàn)結(jié)構(gòu)痢虹,對像容器內(nèi)部實(shí)現(xiàn)結(jié)構(gòu)(而非抽象接口)的變化將因其客戶代碼的頻繁變化奖唯,帶來了代碼的維護(hù)性臭埋、擴(kuò)展性等弊端臀玄。

要點(diǎn)總結(jié):

?Composite模式采用樹形結(jié)構(gòu)來實(shí)現(xiàn)普遍存在的對像容器,從而將“一對多”的關(guān)系轉(zhuǎn)化為“一對一”的關(guān)系荣恐,使得客戶代碼可以一致的(復(fù)用)處理對象和對象容器叠穆,無需關(guān)心處理的是單個對象還是組合的對象容器

?將“客戶代碼與復(fù)雜的對象容器結(jié)構(gòu)”解耦是Composite的核心思想硼被,解耦之后渗磅,客戶代碼將與純粹的抽象接口——而非對像容器的內(nèi)部實(shí)現(xiàn)結(jié)構(gòu)——發(fā)生依賴始鱼,從而更能“應(yīng)對變化”。

?Composite模式在具體實(shí)現(xiàn)中起暮,可以讓父對象中的子對象反向追溯负懦;如果父對象有頻繁的遍歷需求,可使用緩存技巧來改善效率焙矛。

迭代器Iterator:

定義:提供一種方法順序訪問一個聚合對象中的各個元素,而又不暴露(隔離變化,穩(wěn)定)該對象的內(nèi)部表示抛猫。

動機(jī):在軟件構(gòu)建中闺金,集合對象內(nèi)部結(jié)構(gòu)常常變化各異。但由于這些集合對像败匹,我們希望在不暴露其內(nèi)部結(jié)構(gòu)的同時掀亩,可以讓外部客戶代碼透明的訪問其中包含的元素槽棍;同時這種“透明遍歷”也為“同一種算法在多種集合對象上進(jìn)行操作”提供了可能抬驴。使用面向?qū)ο蠹夹g(shù)將這種遍歷機(jī)制抽象為“迭代器對象”為“因?qū)ψ兓械募蠈ο蟆碧峁┝艘环N優(yōu)雅的方式布持。

要點(diǎn)總結(jié):

?迭代抽象:訪問一個聚合對象的內(nèi)容而無需暴露他的內(nèi)部表示。

?迭代多態(tài):為遍歷不同的集合結(jié)構(gòu)提供一個統(tǒng)一的接口按傅,從而支持同樣的算法在不同的集合結(jié)構(gòu)上進(jìn)行操作芙委。

?迭代器健壯性考慮:便利的同時更改迭代器所在的集合結(jié)構(gòu)灌侣,會導(dǎo)致問題侧啼。

責(zé)任鏈Chain of Resposibility:

定義:使多個對像都有機(jī)會處理請求,從而避免請求的發(fā)送者和接收者之間的耦合關(guān)系皮壁。將這些對像連成一條鏈,并沿著這條鏈傳遞請求虑瀑,直到有一個對象處理它為止舌狗。

動機(jī):在軟件構(gòu)建的過程中扔水,一個請求可能被多個對象處理魔市,但是每個請求在運(yùn)行時只能有一個接受者待德,如果顯示制定,將必不可少的帶來請求發(fā)送者與接受者的耦合谈截。

要點(diǎn)總結(jié):

?Chain of Responsibility模式的應(yīng)用場合在于“一個請求可能有多個接受者簸喂,但是最后真正接受者只有一個”燎潮,這時候請求發(fā)送者與接受者的耦合可能出現(xiàn)“變化脆弱”的癥狀确封,職責(zé)鏈的目的就是將二者解耦,從而更好的應(yīng)對變化颜曾。

?應(yīng)用了指責(zé)連模式后泛豪,對象的指責(zé)分派將更具靈活性。我們可以在運(yùn)行時動態(tài)添加/修改請求的處理指責(zé)诡曙。

?如果請求傳遞到職責(zé)鏈的末尾仍得不到處理价卤,應(yīng)該有一個合理的缺省機(jī)制。這也是每一個接受者對象的責(zé)任床嫌,而不是發(fā)出請求的對象的責(zé)任既鞠。

“行為變化”模式 :在組建的構(gòu)建過程中,組建行為的變化經(jīng)常導(dǎo)致組建本身劇烈的變化五续「砑荩“行為變化”模式將組建的行為和組建本身進(jìn)行解耦它碎,從而主持組件的變化,實(shí)現(xiàn)兩者之間的松耦合扳肛。

典型模式:Command 挖息、Visitor

命令模式Command

定義:將一個請求(行為)封裝為對象套腹,從而使你可用不同的請求电禀,對客戶進(jìn)行參數(shù)化笤休;對請求排隊(duì)或記錄請求日志以及支持可撤銷的操作。

動機(jī):在軟件構(gòu)建構(gòu)成中葫松,“行為請求者”與“行為實(shí)現(xiàn)者”通常呈現(xiàn)一種“緊耦合”。但在某些場合——比如需要對行為進(jìn)行“記錄咕娄、撤銷(undo)圣勒、事務(wù)”等圣贸,這種無法抵御變化的緊耦合是不合適的吁峻。

要點(diǎn)總結(jié):

?Command模式的根本目的在于“行為請求者”與“行為實(shí)現(xiàn)者”解耦,在面向?qū)ο蟮恼Z言中用含,常見的實(shí)現(xiàn)手段是“將行為抽象為對象”

?實(shí)現(xiàn)Command接口的具體命令對象ConcreteCommand有時候根據(jù)需要可能會保存一些額外的狀態(tài)信息啄骇。

?通過使用Composite模式瘟斜,可以將多個“命令”封裝為一個“符合命令”MacroCommand Command模式與C++中的函數(shù)對像有些類似螺句。但兩者定義行為接口的規(guī)范有所區(qū)別:Command以面向?qū)ο笾械摹敖涌?實(shí)現(xiàn)”來定義行為接口規(guī)范,更嚴(yán)格趟妥,但有性能損失佣蓉;C++函數(shù)對象以函數(shù)簽名來定義行為接口規(guī)范,更靈活疚膊,性能能高。

訪問者Visitor

定義:表示一個作用與某對像結(jié)構(gòu)中的各元素的操作虾标。使得可以在不改變(穩(wěn)定)各元素的類的前提下定義(擴(kuò)展)作用于這些元素的新操作(變化)寓盗。

動機(jī):在軟件構(gòu)建的過程中,由于需求的改變,某些類層次結(jié)構(gòu)中常常需要增加新的行為(方法)傀蚌。如果直接在類中做這樣的更改基显,將會給子類帶來很繁重的變更負(fù)擔(dān),甚至破壞原有設(shè)計(jì)善炫。

Visitor的缺點(diǎn):對于Visitor來說撩幽,不僅僅需要Vistor和Element需要穩(wěn)定,同時也需要ConcreteElementA和ConcreteElement這兩個類也保持穩(wěn)定箩艺,而這個條件是很難保證的窜醉。如果新增加了Element的子類,那么Visitor的基類就需要改變,同時也會牽扯到ConcreteVisitor藤抡。所以這就是Vistor的缺點(diǎn)棋蚌。Visitor的條件很難達(dá)成。

要點(diǎn)總結(jié):

??Vistor模式通過所謂的雙重分發(fā)(double dispatch)來實(shí)現(xiàn)現(xiàn)在不更改(不添加新的操作-編譯時)Element類層次結(jié)構(gòu)的前提下,在運(yùn)行時透明地為類層次結(jié)構(gòu)上的各個類動態(tài)添加新的操作(支持變化)颊埃。

?所謂雙重分發(fā)即Vistor模式中包括了兩個多態(tài)分發(fā)(注意其中的多態(tài)機(jī)制):第一個accept方法的多態(tài)解析榨呆;第二個visitElementX方法的多態(tài)解析。

?Visitor模式最大的缺點(diǎn)在于擴(kuò)展類層次結(jié)構(gòu)(增添新的Element子類)宾尚,會導(dǎo)致Visitor類的改變澳化。因此Visitor模式適用于“Element類層次結(jié)構(gòu)穩(wěn)定,而其中的操作卻進(jìn)場面臨頻繁改動”瑞你。

“領(lǐng)域規(guī)則”模式:在特定領(lǐng)域內(nèi)虏缸,某些變化雖然頻繁甲献,但可以抽象為某種規(guī)則慨灭。這時候,結(jié)合特定領(lǐng)域诲宇,將問題抽象為語法規(guī)則吕粗,從而給出該領(lǐng)域下的一般性解決方案。

典型模式 :Interpreter

解析器Interpreter:

定義:?給定一個語言,定義它的文法的一種表示,并定義一種解釋器厢汹,這個解釋器使用該表示來解釋語言中的句子凡蜻。

動機(jī):在軟件構(gòu)建過程中舰讹,如果某一特定領(lǐng)域的問題比較復(fù)雜,類似的結(jié)構(gòu)不斷的重復(fù)出現(xiàn)素标,如果使用普通的變成方式來實(shí)現(xiàn)將面臨非常頻繁的變化。在這種情況下袜香,將特定領(lǐng)域的問題表達(dá)為某種語法規(guī)則下的句子,然后構(gòu)建一個解析器來解釋這樣的句子欢策,從而達(dá)到解決問題的目的猜敢。

要點(diǎn)總結(jié):

??Interpreter模式的應(yīng)用場合是Interpreter模式應(yīng)用中的難點(diǎn)胯盯,只有滿足“業(yè)務(wù)規(guī)則頻繁變化泞边,且類似的結(jié)構(gòu)不斷重復(fù)出現(xiàn),并且容易抽象為語法規(guī)則的問題”才適合使用Interpreter模式。

??使用Interpreter模式來表示文法規(guī)則,從而可以使用面向?qū)ο蠹记蓙矸奖愕亍皵U(kuò)展”文法

?Interpreter模式比較適合簡單的文法表示严沥,對于復(fù)雜的文法表示,Interpreter模式會產(chǎn)生比較大的類層次結(jié)構(gòu)峡蟋,需要求助于語法分析生成器這樣的標(biāo)準(zhǔn)工具夸楣。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末孵班,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌批狐,老刑警劉巖困乒,帶你破解...
    沈念sama閱讀 221,888評論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件吱抚,死亡現(xiàn)場離奇詭異秘豹,居然都是意外死亡岸更,警方通過查閱死者的電腦和手機(jī)评肆,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,677評論 3 399
  • 文/潘曉璐 我一進(jìn)店門缸榄,熙熙樓的掌柜王于貴愁眉苦臉地迎上來瑞筐,“玉大人,你說我怎么就攤上這事腊瑟【奂伲” “怎么了?”我有些...
    開封第一講書人閱讀 168,386評論 0 360
  • 文/不壞的土叔 我叫張陵闰非,是天一觀的道長膘格。 經(jīng)常有香客問我,道長财松,這世上最難降的妖魔是什么瘪贱? 我笑而不...
    開封第一講書人閱讀 59,726評論 1 297
  • 正文 為了忘掉前任,我火速辦了婚禮辆毡,結(jié)果婚禮上菜秦,老公的妹妹穿的比我還像新娘。我一直安慰自己舶掖,他們只是感情好球昨,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,729評論 6 397
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著眨攘,像睡著了一般主慰。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上鲫售,一...
    開封第一講書人閱讀 52,337評論 1 310
  • 那天共螺,我揣著相機(jī)與錄音,去河邊找鬼情竹。 笑死藐不,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播佳吞,決...
    沈念sama閱讀 40,902評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼棉安!你這毒婦竟也來了底扳?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,807評論 0 276
  • 序言:老撾萬榮一對情侶失蹤贡耽,失蹤者是張志新(化名)和其女友劉穎衷模,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體蒲赂,經(jīng)...
    沈念sama閱讀 46,349評論 1 318
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡阱冶,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,439評論 3 340
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了滥嘴。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片木蹬。...
    茶點(diǎn)故事閱讀 40,567評論 1 352
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖若皱,靈堂內(nèi)的尸體忽然破棺而出镊叁,到底是詐尸還是另有隱情,我是刑警寧澤走触,帶...
    沈念sama閱讀 36,242評論 5 350
  • 正文 年R本政府宣布晦譬,位于F島的核電站,受9級特大地震影響互广,放射性物質(zhì)發(fā)生泄漏敛腌。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,933評論 3 334
  • 文/蒙蒙 一惫皱、第九天 我趴在偏房一處隱蔽的房頂上張望像樊。 院中可真熱鬧,春花似錦旅敷、人聲如沸凶硅。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,420評論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽足绅。三九已至,卻和暖如春韩脑,著一層夾襖步出監(jiān)牢的瞬間氢妈,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,531評論 1 272
  • 我被黑心中介騙來泰國打工段多, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留首量,地道東北人。 一個月前我還...
    沈念sama閱讀 48,995評論 3 377
  • 正文 我出身青樓,卻偏偏與公主長得像加缘,于是被迫代替她去往敵國和親鸭叙。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,585評論 2 359

推薦閱讀更多精彩內(nèi)容

  • 病房里發(fā)現(xiàn)一個很有趣的現(xiàn)象,經(jīng)逞看到老奶奶無微不至地照顧著患病的老爺爺宋下,卻很少看到老爺爺照顧患病的老奶奶。 這普遍...
    原野花開閱讀 1,315評論 8 4
  • 燈會劃破夜,影子會藏著秘密各吨,自行車和我一同走過這條街道枝笨。什么夜最美之類的話從來不適合我。只有那一年四季不變的街...
    eds陳明閱讀 235評論 0 1
  • 第十四章白鳥之死 看著米蘭那嚴(yán)肅的表情揭蜒,我決定認(rèn)真對待米蘭的焦慮伺帘,除非,我想像拆凌一的桃花一樣忌锯,把米蘭和于天這段姻...
    筆間流年閱讀 206評論 0 1
  • 文/館長小跟班 圖/蘇蘇 (合影經(jīng)霧化處理) 認(rèn)識弘辰大哥第725天偶垮,今日終于見了面张咳。 弘辰大哥在無錫打拼很多年,...
    館長小跟班閱讀 889評論 0 17
  • 親愛的伙伴們似舵,大家現(xiàn)在好脚猾,我是五組41號的呂亮鴿。又到了我們每周一檢的檢視會砚哗,我相信每位伙伴通過這個平臺都在不同程...
    宛塵兒閱讀 144評論 0 0