由于之前的愛(ài)上博客街要關(guān)閉材蹬,將之前的文章移至這里舰始,以便查閱源请。之后的文章主要是在簡(jiǎn)書上發(fā)表。
為什么使用設(shè)計(jì)模式
使用設(shè)計(jì)模式的根本原因是適應(yīng)變化,提高代碼復(fù)用率,使軟件更具有可維護(hù)性和可擴(kuò)展性。并且悦昵,在進(jìn)行設(shè)計(jì)的時(shí)候,也需要遵循以下六個(gè)原則:單一職責(zé)原則晌畅、里氏代替原則但指、依賴倒置原則、接口隔離原則抗楔、合成復(fù)用原則和迪米特法則棋凳。下面就分別介紹了每種設(shè)計(jì)原則。
一连躏、設(shè)計(jì)原則
總原則:開閉原則(Open-Closed Principle)
開閉原則即OCP(Open-Closed Principle縮寫)原則剩岳,該原則強(qiáng)調(diào)的是:一個(gè)軟件實(shí)體(指的類、函數(shù)入热、模塊等)應(yīng)該對(duì)擴(kuò)展開放拍棕,對(duì)修改關(guān)閉。即每次發(fā)生變化時(shí)勺良,要通過(guò)添加新的代碼來(lái)增強(qiáng)現(xiàn)有類型的行為绰播,而不是修改原有的代碼。
符合開閉原則的最好方式是提供一個(gè)固有的接口尚困,然后讓所有可能發(fā)生變化的類實(shí)現(xiàn)該接口蠢箩,讓固定的接口與相關(guān)對(duì)象進(jìn)行交互
1.1 單一職責(zé)原則
就一個(gè)類而言,應(yīng)該只有一個(gè)引起它變化的原因事甜。如果一個(gè)類承擔(dān)的職責(zé)過(guò)多谬泌,就等于把這些職責(zé)耦合在一起,一個(gè)職責(zé)的變化可能會(huì)影響到其他的職責(zé)逻谦,另外掌实,把多個(gè)職責(zé)耦合在一起,也會(huì)影響復(fù)用性
1.2 里氏代替原則(Liskov Substitution Principle)
其核心是子類可以代替父類邦马,但是父類并不一定可以代替子類
Liskov Substitution Principle,LSP(里氏代替原則)指的是子類必須替換掉它們的父類型贱鼻。也就是說(shuō),在軟件開發(fā)過(guò)程中勇婴,子類替換父類后忱嘹,程序的行為是一樣的。只有當(dāng)子類替換掉父類后耕渴,此時(shí)軟件的功能不受影響時(shí),父類才能真正地被復(fù)用齿兔,而子類也可以在父類的基礎(chǔ)上添加新的行為
1.3 依賴倒置原則
其核心是抽象不應(yīng)該依賴于細(xì)節(jié)橱脸,但細(xì)節(jié)應(yīng)該依賴于抽象
依賴倒置(Dependence Inversion Principle, DIP)原則指的是抽象不應(yīng)該依賴于細(xì)節(jié)础米,細(xì)節(jié)應(yīng)該依賴于抽象,也就是提出的 “面向接口編程添诉,而不是面向?qū)崿F(xiàn)編程”屁桑。這樣可以降低客戶與具體實(shí)現(xiàn)的耦合。
1.4 接口隔離原則
其核心是不要單一接口承擔(dān)過(guò)多的職責(zé)
接口隔離原則(Interface Segregation Principle, ISP)指的是使用多個(gè)專門的接口比使用單一的總接口要好栏赴。也就是說(shuō)不要讓一個(gè)單一的接口承擔(dān)過(guò)多的職責(zé)蘑斧,而應(yīng)把每個(gè)職責(zé)分離到多個(gè)專門的接口中,進(jìn)行接口分離须眷。過(guò)于臃腫的接口是對(duì)接口的一種污染竖瘾。
1.5 合成復(fù)用原則
合成復(fù)用原則(Composite Reuse Principle, CRP)就是在一個(gè)新的對(duì)象里面使用一些已有的對(duì)象,使之成為新對(duì)象的一部分花颗。新對(duì)象通過(guò)向這些對(duì)象的委派達(dá)到復(fù)用已用功能的目的捕传。簡(jiǎn)單地說(shuō),就是要盡量使用合成/聚合扩劝,盡量不要使用繼承庸论。
要使用好合成復(fù)用原則,首先需要區(qū)分"Has—A"和“Is—A”的關(guān)系棒呛。
“Is—A”是指一個(gè)類是另一個(gè)類的“一種”聂示,是屬于的關(guān)系,而“Has—A”則不同簇秒,它表示某一個(gè)角色具有某一項(xiàng)責(zé)任催什。導(dǎo)致錯(cuò)誤的使用繼承而不是聚合的常見的原因是錯(cuò)誤地把“Has—A”當(dāng)成“Is—A”.例如:
實(shí)際上,雇員宰睡、經(jīng)歷蒲凶、學(xué)生描述的是一種角色,比如一個(gè)人是“經(jīng)理”必然是“雇員”拆内。在上面的設(shè)計(jì)中旋圆,一個(gè)人無(wú)法同時(shí)擁有多個(gè)角色,是“雇員”就不能再是“學(xué)生”了麸恍,這顯然不合理灵巧,因?yàn)楝F(xiàn)在很多在職研究生,即使雇員也是學(xué)生抹沪。
上面的設(shè)計(jì)的錯(cuò)誤源于把“角色”的等級(jí)結(jié)構(gòu)與“人”的等級(jí)結(jié)構(gòu)混淆起來(lái)了刻肄,誤把“Has—A”當(dāng)作"Is—A"。具體的解決方法就是抽象出一個(gè)角色類:
合成表示一個(gè)整體與部分的關(guān)系融欧,指依托整體而存在的關(guān)系(整體和部分不能分開)敏弃,聚合也表示一個(gè)整體與部分的關(guān)系,但整體和部分可以分開噪馏。
1.6 迪米特法則
迪米特法則(Law of Demeter麦到,LoD)又叫最少知識(shí)原則(Least Knowledge Principle绿饵,LKP),指的是一個(gè)對(duì)象應(yīng)當(dāng)對(duì)其他對(duì)象有盡可能少的了解瓶颠。也就是說(shuō)拟赊,一個(gè)模塊或?qū)ο髴?yīng)盡量少的與其他實(shí)體之間發(fā)生相互作用,使得系統(tǒng)功能模塊相對(duì)獨(dú)立粹淋,這樣當(dāng)一個(gè)模塊修改時(shí)吸祟,影響的模塊就會(huì)越少,擴(kuò)展起來(lái)更加容易桃移。
關(guān)于迪米特法則其他的一些表述有:只與你直接的朋友們通信屋匕;不要跟“陌生人”說(shuō)話。
外觀模式(Facade Pattern)和中介者模式(Mediator Pattern)就使用了迪米特法則谴轮。
設(shè)計(jì)模式的分類
總體來(lái)說(shuō)設(shè)計(jì)模式分為三大類
創(chuàng)建型模式:?jiǎn)卫J匠次痢⒐S方法模式、抽象工廠模式第步、建造者模式和原型模式
結(jié)構(gòu)型模式:適配器模式疮装、橋接模式、裝飾者模式粘都、組合模式廓推、外觀模式、享元模式和代理模式
行為型模式:模板方法模式翩隧、命令模式樊展、迭代器模式、觀察者模式堆生、中介者模式专缠、狀態(tài)模式、策略模式淑仆、責(zé)任鏈模式涝婉、訪問(wèn)者模式、解釋器模式和備忘錄模式
創(chuàng)建型模式
創(chuàng)建型模式就是用來(lái)創(chuàng)建對(duì)象的模式蔗怠,抽象了實(shí)例化的過(guò)程墩弯。所有的創(chuàng)建型模式都有兩個(gè)共同點(diǎn)。第一寞射,它們都將系統(tǒng)使用哪些具體類的信息封裝起來(lái)渔工;第二,它們隱藏了這些類的實(shí)例是如何被創(chuàng)建和組織的桥温。創(chuàng)建型模式包括單例模式引矩、工廠方法模式、抽象工廠模式、建造者模式和原型模式脓魏。
單例模式:解決的是實(shí)例化對(duì)象的個(gè)數(shù)的問(wèn)題兰吟,比如抽象工廠中的工廠通惫、對(duì)象池等茂翔,除了Singleton之外,其他創(chuàng)建型模式解決的都是 new 所帶來(lái)的耦合關(guān)系履腋;
工廠方法:創(chuàng)建單個(gè)對(duì)象珊燎,在Abstract Factory有使用到;
抽象工廠:創(chuàng)建一系列相互依賴對(duì)象遵湖,并能在運(yùn)行時(shí)改變系列悔政;
原型模式:通過(guò)拷貝原型來(lái)創(chuàng)建新的對(duì)象;
建造者模式:可以將部件和其組裝過(guò)程分開延旧,一步一步創(chuàng)建一個(gè)復(fù)雜的對(duì)象谋国;
工廠方法,抽象工廠,建造者都需要一個(gè)額外的工廠類來(lái)負(fù)責(zé)實(shí)例化“一個(gè)對(duì)象”迁沫,而Prototype則是通過(guò)原型(一個(gè)特殊的工廠類)來(lái)克隆“易變對(duì)象”芦瘾。
結(jié)構(gòu)型模式
結(jié)構(gòu)型模式,顧名思義討論的是類和對(duì)象的結(jié)構(gòu) 集畅,主要用來(lái)處理類或?qū)ο蟮慕M合近弟。它包括兩種類型,一是類結(jié)構(gòu)型模式挺智,指的是采用繼承機(jī)制來(lái)組合接口或?qū)崿F(xiàn)祷愉;二是對(duì)象結(jié)構(gòu)型模式,指的是通過(guò)組合對(duì)象的方式來(lái)實(shí)現(xiàn)新的功能赦颇。它包括適配器模式二鳄、橋接模式、裝飾者模式媒怯、組合模式订讼、外觀模式、享元模式和代理模式沪摄。
適配器模式:注重轉(zhuǎn)換接口躯嫉,將不吻合的接口適配對(duì)接;
橋接模式:注重分離接口與其實(shí)現(xiàn)杨拐,支持多維度變化祈餐;
組合模式:注重統(tǒng)一接口,將“一對(duì)多”的關(guān)系轉(zhuǎn)化為“一對(duì)一”的關(guān)哄陶;
裝飾者模式:注重穩(wěn)定接口帆阳,在此前提下為對(duì)象擴(kuò)展功能;
外觀模式:注重簡(jiǎn)化接口,簡(jiǎn)化組件系統(tǒng)與外部客戶程序的依賴關(guān)蜒谤;
享元模式:注重保留接口山宾,在內(nèi)部使用共享技術(shù)對(duì)對(duì)象存儲(chǔ)進(jìn)行優(yōu)化;
代理模式:注重假借接口鳍徽,增加間接層來(lái)實(shí)現(xiàn)靈活控制资锰。
行為型模式(Behavioral Patterns)
行為型模式是對(duì)在不同對(duì)象之間劃分責(zé)任和算法的抽象化。行為模式不僅僅關(guān)于類和對(duì)象阶祭,還關(guān)于它們之間的相互作用绷杜。行為型模式又分為類的行為模式和對(duì)象的行為模式兩種。
類的行為模式——使用繼承關(guān)系在幾個(gè)類之間分配行為濒募。
對(duì)象的行為模式——使用對(duì)象聚合的方式來(lái)分配行為鞭盟。
行為型模式包括11種模式:模板方法模式、命令模式瑰剃、迭代器模式齿诉、觀察者模式、中介者模式晌姚、狀態(tài)模式粤剧、策略模式、責(zé)任鏈模式舀凛、訪問(wèn)者模式俊扳、解釋器模式和備忘錄模式。
模板方法模式:封裝算法結(jié)構(gòu)猛遍,定義算法骨架馋记,支持算法子步驟變化;
命令模式:注重將請(qǐng)求封裝為對(duì)象懊烤,支持請(qǐng)求的變化梯醒,通過(guò)將一組行為抽象為對(duì)象,實(shí)現(xiàn)行為請(qǐng)求者和行為實(shí)現(xiàn)者之間的解耦腌紧;
迭代器模式:注重封裝特定領(lǐng)域變化茸习,支持集合的變化,屏蔽集合對(duì)象內(nèi)部復(fù)雜結(jié)構(gòu)壁肋,提供客戶程序?qū)λ耐该鞅闅v号胚;
觀察者模式:注重封裝對(duì)象通知,支持通信對(duì)象的變化浸遗,實(shí)現(xiàn)對(duì)象狀態(tài)改變猫胁,通知依賴它的對(duì)象并更新;
中介者模式:注重封裝對(duì)象間的交互跛锌,通過(guò)封裝一系列對(duì)象之間的復(fù)雜交互弃秆,使他們不需要顯式相互引用,實(shí)現(xiàn)解耦;
狀態(tài)模式:注重封裝與狀態(tài)相關(guān)的行為菠赚,支持狀態(tài)的變化脑豹,通過(guò)封裝對(duì)象狀態(tài),從而在其內(nèi)部狀態(tài)改變時(shí)改變它的行為衡查;
策略模式:注重封裝算法瘩欺,支持算法的變化,通過(guò)封裝一系列算法峡捡,從而可以隨時(shí)獨(dú)立于客戶替換算法击碗;
責(zé)任鏈模式:注重封裝對(duì)象責(zé)任筑悴,支持責(zé)任的變化们拙,通過(guò)動(dòng)態(tài)構(gòu)建職責(zé)鏈,實(shí)現(xiàn)事務(wù)處理阁吝;
訪問(wèn)者模式:注重封裝對(duì)象操作變化砚婆,支持在運(yùn)行時(shí)為類結(jié)構(gòu)添加新的操作,在類層次結(jié)構(gòu)中突勇,在不改變各類的前提下定義作用于這些類實(shí)例的新的操作装盯;
備忘錄模式:注重封裝對(duì)象狀態(tài)變化,支持狀態(tài)保存甲馋、恢復(fù)埂奈;
解釋器模式:注重封裝特定領(lǐng)域變化,支持領(lǐng)域問(wèn)題的頻繁變化定躏,將特定領(lǐng)域的問(wèn)題表達(dá)為某種語(yǔ)法規(guī)則下的句子账磺,然后構(gòu)建一個(gè)解釋器來(lái)解釋這樣的句子,從而達(dá)到解決問(wèn)題的目的痊远。