1.???????單例模式:
實(shí)現(xiàn)方式:
a) 將被實(shí)現(xiàn)的類的構(gòu)造方法設(shè)計(jì)成private的。
b) 添加此類引用的靜態(tài)成員變量,并為其實(shí)例化箩溃。
c)? 在被實(shí)現(xiàn)的類中提供公共的CreateInstance函數(shù),返回實(shí)例化的此類,就是b中的靜態(tài)成員變量嗜憔。
應(yīng)用場(chǎng)景:
優(yōu)點(diǎn):
1.在單例模式中,活動(dòng)的單例只有一個(gè)實(shí)例氏仗,對(duì)單例類的所有實(shí)例化得到的都是相同的一個(gè)實(shí)例吉捶。這樣就 防止其它對(duì)象對(duì)自己的實(shí)例化,確保所有的對(duì)象都訪問一個(gè)實(shí)例
2.單例模式具有一定的伸縮性皆尔,類自己來(lái)控制實(shí)例化進(jìn)程站绪,類就在改變實(shí)例化進(jìn)程上有相應(yīng)的伸縮性掷匠。
3.提供了對(duì)唯一實(shí)例的受控訪問攒霹。
4.由于在系統(tǒng)內(nèi)存中只存在一個(gè)對(duì)象厘托,因此可以 節(jié)約系統(tǒng)資源,當(dāng) 需要頻繁創(chuàng)建和銷毀的對(duì)象時(shí)單例模式無(wú)疑可以提高系統(tǒng)的性能流炕。
5.允許可變數(shù)目的實(shí)例澎现。
6.避免對(duì)共享資源的多重占用仅胞。
缺點(diǎn):
1.不適用于變化的對(duì)象,如果同一類型的對(duì)象總是要在不同的用例場(chǎng)景發(fā)生變化剑辫,單例就會(huì)引起數(shù)據(jù)的錯(cuò)誤饼问,不能保存彼此的狀態(tài)。
2.由于單利模式中沒有抽象層揭斧,因此單例類的擴(kuò)展有很大的困難。
3.單例類的職責(zé)過重峻堰,在一定程度上違背了“單一職責(zé)原則”讹开。
4.濫用單例將帶來(lái)一些負(fù)面問題,如為了節(jié)省資源將數(shù)據(jù)庫(kù)連接池對(duì)象設(shè)計(jì)為的單例類捐名,可能會(huì)導(dǎo)致共享連接池對(duì)象的程序過多而出現(xiàn)連接池溢出旦万;如果實(shí)例化的對(duì)象長(zhǎng)時(shí)間不被利用,系統(tǒng)會(huì)認(rèn)為是垃圾而被回收镶蹋,這將導(dǎo)致對(duì)象狀態(tài)的丟失成艘。
使用注意事項(xiàng):
1.使用時(shí)不能用反射模式創(chuàng)建單例,否則會(huì)實(shí)例化一個(gè)新的對(duì)象
2.使用懶單例模式時(shí)注意線程安全問題
3.單例模式和懶單例模式構(gòu)造方法都是私有的贺归,因而是不能被繼承的淆两,有些單例模式可以被繼承(如登記式模式)
適用場(chǎng)景:
單例模式只允許創(chuàng)建一個(gè)對(duì)象,因此節(jié)省內(nèi)存拂酣,加快對(duì)象訪問速度秋冰,因此對(duì)象需要被公用的場(chǎng)合適合使用,如多個(gè)模塊使用同一個(gè)數(shù)據(jù)源連接對(duì)象等等婶熬。如:
1.需要頻繁實(shí)例化然后銷毀的對(duì)象剑勾。
2.創(chuàng)建對(duì)象時(shí)耗時(shí)過多或者耗資源過多,但又經(jīng)常用到的對(duì)象赵颅。
3.有狀態(tài)的工具類對(duì)象虽另。
4.頻繁訪問數(shù)據(jù)庫(kù)或文件的對(duì)象。
以下都是單例模式的經(jīng)典使用場(chǎng)景:
1.資源共享的情況下饺谬,避免由于資源操作時(shí)導(dǎo)致的性能或損耗等捂刺。如上述中的日志文件,應(yīng)用配置募寨。
2.控制資源的情況下叠萍,方便資源之間的互相通信。如線程池等绪商。
應(yīng)用場(chǎng)景舉例:
1.外部資源:每臺(tái)計(jì)算機(jī)有若干個(gè)打印機(jī)苛谷,但只能有一個(gè)PrinterSpooler,以避免兩個(gè)打印作業(yè)同時(shí)輸出到打印機(jī)格郁。內(nèi)部資源:大多數(shù)軟件都有一個(gè)(或多個(gè))屬性文件存放系統(tǒng)配置腹殿,這樣的系統(tǒng)應(yīng)該有一個(gè)對(duì)象管理這些屬性文件
2. Windows的TaskManager(任務(wù)管理器)就是很典型的單例模式(這個(gè)很熟悉吧)独悴,想想看,是不是呢锣尉,你能打開兩個(gè)windows task manager嗎刻炒? 不信你自己試試看哦~
3. windows的Recycle Bin(回收站)也是典型的單例應(yīng)用。在整個(gè)系統(tǒng)運(yùn)行過程中自沧,回收站一直維護(hù)著僅有的一個(gè)實(shí)例坟奥。
4. 網(wǎng)站的計(jì)數(shù)器,一般也是采用單例模式實(shí)現(xiàn)拇厢,否則難以同步爱谁。
5. 應(yīng)用程序的日志應(yīng)用,一般都何用單例模式實(shí)現(xiàn)孝偎,這一般是由于共享的日志文件一直處于打開狀態(tài)访敌,因?yàn)橹荒苡幸粋€(gè)實(shí)例去操作,否則內(nèi)容不好追加衣盾。
6. Web應(yīng)用的配置對(duì)象的讀取寺旺,一般也應(yīng)用單例模式,這個(gè)是由于配置文件是共享的資源势决。
7. 數(shù)據(jù)庫(kù)連接池的設(shè)計(jì)一般也是采用單例模式阻塑,因?yàn)閿?shù)據(jù)庫(kù)連接是一種數(shù)據(jù)庫(kù)資源。數(shù)據(jù)庫(kù)軟件系統(tǒng)中使用數(shù)據(jù)庫(kù)連接池果复,主要是節(jié)省打開或者關(guān)閉數(shù)據(jù)庫(kù)連接所引起的效率損耗叮姑,這種效率上的損耗還是非常昂貴的,因?yàn)楹斡脝卫J絹?lái)維護(hù)据悔,就可以大大降低這種損耗传透。
8. 多線程的線程池的設(shè)計(jì)一般也是采用單例模式,這是由于線程池要方便對(duì)池中的線程進(jìn)行控制极颓。
9. 操作系統(tǒng)的文件系統(tǒng)朱盐,也是大的單例模式實(shí)現(xiàn)的具體例子,一個(gè)操作系統(tǒng)只能有一個(gè)文件系統(tǒng)菠隆。
10. HttpApplication 也是單位例的典型應(yīng)用兵琳。熟悉ASP.Net(IIS)的整個(gè)請(qǐng)求生命周期的人應(yīng)該知道HttpApplication也是單例模式,所有的HttpModule都共享一個(gè)HttpApplication實(shí)例.
2.???????策略模式:
實(shí)現(xiàn)方式:
a)????? 提供公共接口或抽象類骇径,定義需要使用的策略方法躯肌。(策略抽象類)
b)????? 多個(gè)實(shí)現(xiàn)的策略抽象類的實(shí)現(xiàn)類。(策略實(shí)現(xiàn)類)
c)?????? 環(huán)境類破衔,對(duì)多個(gè)實(shí)現(xiàn)類的封裝清女,提供接口類型的成員量,可以在客戶端中切換晰筛。
d)????? 客戶端 調(diào)用環(huán)境類 進(jìn)行不同策略的切換嫡丙。
注:Jdk中的TreeSet和?TreeMap的排序功能就是使用了策略模式拴袭。
(1)策略模式提供了管理相關(guān)的算法族的辦法曙博。策略類的等級(jí)結(jié)構(gòu)定義了一個(gè)算法或行為族拥刻。恰當(dāng)使用繼承可以把公共的代碼移到父類里面,從而避免代碼重復(fù)父泳。
“愫摺(2)使用策略模式可以避免使用多重條件(if-else)語(yǔ)句。多重條件語(yǔ)句不易維護(hù)惠窄,它把采取哪一種算法或采取哪一種行為的邏輯與算法或行為的邏輯混合在一起蒸眠,統(tǒng)統(tǒng)列在一個(gè)多重條件語(yǔ)句里面,比使用繼承的辦法還要原始和落后睬捶。
(1)客戶端必須知道所有的策略類近刘,并自行決定使用哪一個(gè)策略類擒贸。這就意味著客戶端必須理解這些算法的區(qū)別,以便適時(shí)選擇恰當(dāng)?shù)乃惴惥蹩省Q言之介劫,策略模式只適用于客戶端知道算法或行為的情況。
“噶堋(2)由于策略模式把每個(gè)具體的策略實(shí)現(xiàn)都單獨(dú)封裝成為類座韵,如果備選的策略很多的話,那么對(duì)象的數(shù)目就會(huì)很可觀踢京。
3.???????代理模式:
一)靜態(tài)代理
實(shí)現(xiàn)方式:
a) 為真實(shí)類和代理類提供的公共接口或抽象類誉碴。(租房)
b) 真實(shí)類,具體實(shí)現(xiàn)邏輯瓣距,實(shí)現(xiàn)或繼承a黔帕。(房主向外租房)
c)? 代理類,實(shí)現(xiàn)或繼承a蹈丸,有對(duì)b的引用成黄,調(diào)用真實(shí)類的具體實(shí)現(xiàn)。(中介)
d) 客戶端逻杖,調(diào)用代理類實(shí)現(xiàn)對(duì)真實(shí)類的調(diào)用奋岁。(租客租房)
二)動(dòng)態(tài)代理
實(shí)現(xiàn)方式:
a) 公共的接口(必須是接口,因?yàn)镻roxy類的newproxyinstance方法的第二參數(shù)必須是個(gè)接口類型的Class)
b) 多個(gè)真實(shí)類荸百,具體實(shí)現(xiàn)的業(yè)務(wù)邏輯闻伶。
c)? 代理類,實(shí)現(xiàn)InvocationHandler接口够话,提供Object成員變量虾攻,和Set方法铡买,便于客戶端切換。
d) 客戶端霎箍,獲得代理類的實(shí)例奇钞,為object實(shí)例賦值,調(diào)用Proxy.newproxyinstance方法在程序運(yùn)行時(shí)生成繼承公共接口的實(shí)例漂坏,調(diào)用相應(yīng)方法景埃,此時(shí)方法的執(zhí)行由代理類實(shí)現(xiàn)的Invoke方法接管。
jdk動(dòng)態(tài)代理使用的局限性:
通過反射類Proxy和InvocationHandler回調(diào)接口實(shí)現(xiàn)的jdk動(dòng)態(tài)代理顶别,要求委托類必須實(shí)現(xiàn)一個(gè)接口谷徙,但事實(shí)上并不是所有類都有接口,對(duì)于沒有實(shí)現(xiàn)接口的類驯绎,便無(wú)法使用該方方式實(shí)現(xiàn)動(dòng)態(tài)代理完慧。
4.???????觀察者模式:
觀察者模式是對(duì)象的行為模式,又叫發(fā)布-訂閱(Publish/Subscribe)模式剩失、模型-視圖(Model/View)模式屈尼、源-監(jiān)聽器(Source/Listener)模式或從屬者(Dependents)模式。
實(shí)現(xiàn)方式:
a) 角色抽象類(提供對(duì)觀察者的添加拴孤,刪除和通知功能)脾歧。
b) 角色具體類,實(shí)現(xiàn)a演熟,維護(hù)一個(gè)c的集合(對(duì)角色抽象類的實(shí)現(xiàn))鞭执。
c)? 觀察者抽象類(被角色通知后實(shí)現(xiàn)的方法)。
d) 觀察者實(shí)現(xiàn)類芒粹,實(shí)現(xiàn)c(多個(gè))兄纺。
注:JDK提供了對(duì)觀察者模式的支持,使用Observable類和Observer接口
兩種模型(推模型和拉模型):
■ 推模型是假定主題對(duì)象知道觀察者需要的數(shù)據(jù)化漆;而拉模型是主題對(duì)象不知道觀察者具體需要什么數(shù)據(jù)囤热,沒有辦法的情況下,干脆把自身傳遞給觀察者获三,讓觀察者自己去按需要取值旁蔼。
■ 推模型可能會(huì)使得觀察者對(duì)象難以復(fù)用,因?yàn)橛^察者的update()方法是按需要定義的參數(shù)疙教,可能無(wú)法兼顧沒有考慮到的使用情況棺聊。這就意味著出現(xiàn)新情況的時(shí)候,就可能提供新的update()方法贞谓,或者是干脆重新實(shí)現(xiàn)觀察者限佩;而拉模型就不會(huì)造成這樣的情況,因?yàn)槔P拖拢瑄pdate()方法的參數(shù)是主題對(duì)象本身祟同,這基本上是主題對(duì)象能傳遞的最大數(shù)據(jù)集合了作喘,基本上可以適應(yīng)各種情況的需要。
5.???????裝飾模式:
實(shí)現(xiàn)方式:
a)???????抽象的被裝飾角色 (所有的角色都要直接或間接的實(shí)現(xiàn)本角色)
b)???????具體的被裝飾角色晕城,實(shí)現(xiàn)或繼承a (被功能擴(kuò)展的角色)
c)???????裝飾角色泞坦,實(shí)現(xiàn)或繼承a (本類有對(duì)a的引用,所有的具體裝飾角色都需要繼承這個(gè)角色)
d)???????多個(gè)具體修飾角色 砖顷,繼承c(對(duì)被裝飾角色的功能擴(kuò)展贰锁,可以任意搭配使用)
意圖:?
動(dòng)態(tài)地給一個(gè)對(duì)象添加一些額外的職責(zé)。就增加功能來(lái)說滤蝠,Decorator模式相比生成子類更為靈活豌熄。該模式以對(duì)客 戶端透明的方式擴(kuò)展對(duì)象的功能。
適用環(huán)境:
(1)在不影響其他對(duì)象的情況下物咳,以動(dòng)態(tài)锣险、透明的方式給單個(gè)對(duì)象添加職責(zé)。
(2)處理那些可以撤消的職責(zé)览闰。
(3)當(dāng)不能采用生成子類的方法進(jìn)行擴(kuò)充時(shí)芯肤。一種情況是,可能有大量獨(dú)立的擴(kuò)展焕济,為支持每一種組合將產(chǎn)生大量的 子類纷妆,使得子類數(shù)目呈爆炸性增長(zhǎng)盔几。另一種情況可能是因?yàn)轭惗x被隱藏晴弃,或類定義不能用于生成子類。
6.??????適配器模式:
適配器模式把一個(gè)類的接口變換成客戶端所期待的另一種接口逊拍,從而使原本因接口不匹配而無(wú)法在一起工作的兩個(gè)類能夠在一起工作上鞠。
1.?????? 類適配器(子類繼承方式)
實(shí)現(xiàn)方式:
a)?????目標(biāo)抽象角色(定義客戶要用的接口)
b)?????適配器(實(shí)現(xiàn)a繼承c,作為一個(gè)轉(zhuǎn)換器被客戶調(diào)用)
c)?????待適配器(真正需要被調(diào)用的)
d)?????客戶端(借用a的實(shí)例調(diào)用c的方法)
2.?????對(duì)象適配器(對(duì)象的組合方式)
實(shí)現(xiàn)方式:
a)?????目標(biāo)抽象角色(定義客戶要用的接口)
b)?????適配器(實(shí)現(xiàn)a芯丧,維護(hù)一個(gè)c的引用芍阎,作為一個(gè)轉(zhuǎn)換器被d調(diào)用)
c)?????待適配器(真正需要被調(diào)用的)
d)?????客戶端(此類,借用a類的實(shí)例調(diào)用c類的方法缨恒,類似靜態(tài)代理谴咸,但是解決的問題不同)
3.?????缺省的方式
實(shí)現(xiàn)方式:
a)?????抽象接口
b)?????實(shí)現(xiàn)a的適配器類(空實(shí)現(xiàn))
c)?????客戶端,繼承b骗露,調(diào)用b中的方法岭佳,不必直接實(shí)現(xiàn)a(直接實(shí)現(xiàn)a需要實(shí)現(xiàn)a中的所有的方法)
1.?????更好的復(fù)用性
系統(tǒng)需要使用現(xiàn)有的類,而此類的接口不符合系統(tǒng)的需要萧锉。那么通過適配器模式就可以讓這些功能得到更好的復(fù)用珊随。
2.?????更好的擴(kuò)展性
在實(shí)現(xiàn)適配器功能的時(shí)候,可以調(diào)用自己開發(fā)的功能,從而自然地?cái)U(kuò)展系統(tǒng)的功能叶洞。
過多的使用適配器鲫凶,會(huì)讓系統(tǒng)非常零亂,不易整體進(jìn)行把握衩辟。比如螟炫,明明看到調(diào)用的是A接口,其實(shí)內(nèi)部被適配成了B接口的實(shí)現(xiàn)惭婿,一個(gè)系統(tǒng)如果太多出現(xiàn)這種情況不恭,無(wú)異于一場(chǎng)災(zāi)難。因此如果不是很有必要财饥,可以不使用適配器换吧,而是直接對(duì)系統(tǒng)進(jìn)行重構(gòu)。
7.??? 命令模式
將一個(gè)請(qǐng)求封裝為一個(gè)對(duì)象钥星,從而可用不同的請(qǐng)求對(duì)客戶進(jìn)行參數(shù)化沾瓦;對(duì)請(qǐng)求排隊(duì)或記錄日志,以及支持可撤銷的操作
將“發(fā)出請(qǐng)求的對(duì)象”和”接收與執(zhí)行這些請(qǐng)求的對(duì)象”分隔開來(lái)谦炒。
實(shí)現(xiàn)方式:
a)?????抽象的命令角色 贯莺, 如:菜單(規(guī)定可以點(diǎn)哪些菜)
b)?????具體的命令角色(實(shí)現(xiàn)a 維護(hù)一個(gè)對(duì)c的引用),如:訂單(已點(diǎn)的菜)
c)?????接收者(具體執(zhí)行命令的角色)宁改,實(shí)際操作時(shí)缕探,很常見使用"聰明"命令對(duì)象,也就是直接實(shí)現(xiàn)了請(qǐng)求还蹲,而不是將工作委托給c (弊端爹耗?) 如:廚師接收訂單后做菜
d)?????調(diào)用者(維護(hù)一個(gè)對(duì)a的引用),如:服務(wù)員負(fù)責(zé)點(diǎn)菜并把訂單推給廚師
e)?????客戶端 調(diào)用d發(fā)出命令進(jìn)而執(zhí)行c的方法谜喊,如:顧客點(diǎn)餐
效果:
1)潭兽、command模式將調(diào)用操作的對(duì)象和實(shí)現(xiàn)該操作的對(duì)象解耦
2)、可以將多個(gè)命令裝配成一個(gè)復(fù)合命令斗遏,復(fù)合命令是Composite模式的一個(gè)實(shí)例
3)山卦、增加新的command很容易,無(wú)需改變已有的類
適用性:
1)诵次、抽象出待執(zhí)行的動(dòng)作以參數(shù)化某對(duì)象
2)账蓉、在不同的時(shí)刻指定、排列和執(zhí)行請(qǐng)求逾一。如請(qǐng)求隊(duì)列
3)铸本、支持取消操作
4)、支持修改日志
5)嬉荆、用構(gòu)建在原語(yǔ)操作上的高層操作構(gòu)造一個(gè)系統(tǒng)归敬。支持事物
8.??? 組合模式
將對(duì)象組合成樹形結(jié)構(gòu)以表示“部分整體”的層次結(jié)構(gòu)。組合模式使得用戶對(duì)單個(gè)對(duì)象和復(fù)雜對(duì)象的使用具有一致性。
實(shí)現(xiàn)方式:
a)?????抽象的構(gòu)件接口 (規(guī)范執(zhí)行的方法)汪茧,b及c都需實(shí)現(xiàn)此接口椅亚,如:Junit中的Test接口
b)?????葉部件(實(shí)現(xiàn)a,最小的執(zhí)行單位)舱污,如:Junit中我們所編寫的測(cè)試用例
c)?????組合類(實(shí)現(xiàn)a并維護(hù)一個(gè)a的集合[多個(gè)b的組合])呀舔,如:Junit中的 TestSuite
d)?????客戶端 可以隨意的將b和c進(jìn)行組合,進(jìn)行調(diào)用
什么情況下使用組合模式:
當(dāng)發(fā)現(xiàn)需求中是體現(xiàn)部分與整體層次結(jié)構(gòu)時(shí)扩灯,以及你希望用戶可以忽略組合對(duì)象與單個(gè)對(duì)象的不同媚赖,統(tǒng)一地使用組合結(jié)構(gòu)中的所有對(duì)象時(shí),就應(yīng)該考慮組合模式了珠插。
9.??? 簡(jiǎn)單工廠模式
就是建立一個(gè)工廠類惧磺,對(duì)實(shí)現(xiàn)了同一接口的一些類進(jìn)行實(shí)例的創(chuàng)建。簡(jiǎn)單工廠模式的實(shí)質(zhì)是由一個(gè)工廠類根據(jù)傳入的參數(shù)捻撑,動(dòng)態(tài)決定應(yīng)該創(chuàng)建哪一個(gè)產(chǎn)品類(這些產(chǎn)品類繼承自一個(gè)父類或接口)的實(shí)例磨隘。
實(shí)現(xiàn)方式:
a)?????抽象產(chǎn)品類(也可以是接口)
b)?????多個(gè)具體的產(chǎn)品類
c)?????工廠類(包括創(chuàng)建a的實(shí)例的方法)
優(yōu)點(diǎn):
工廠類是整個(gè)模式的關(guān)鍵.包含了必要的邏輯判斷,根據(jù)外界給定的信息,決定究竟應(yīng)該創(chuàng)建哪個(gè)具體類的對(duì)象.通過使用工廠類,外界可以從直接創(chuàng)建具體產(chǎn)品對(duì)象的尷尬局面擺脫出來(lái),僅僅需要負(fù)責(zé)“消費(fèi)”對(duì)象就可以了。而不必管這些對(duì)象究竟如何創(chuàng)建及如何組織的.明確了各自的職責(zé)和權(quán)利顾患,有利于整個(gè)軟件體系結(jié)構(gòu)的優(yōu)化番捂。
缺點(diǎn):
由于工廠類集中了所有實(shí)例的創(chuàng)建邏輯,違反了高內(nèi)聚責(zé)任分配原則江解,將全部創(chuàng)建邏輯集中到了一個(gè)工廠類中设预;它所能創(chuàng)建的類只能是事先考慮到的,如果需要添加新的類犁河,則就需要改變工廠類了鳖枕。當(dāng)系統(tǒng)中的具體產(chǎn)品類不斷增多時(shí)候,可能會(huì)出現(xiàn)要求工廠類根據(jù)不同條件創(chuàng)建不同實(shí)例的需求.這種對(duì)條件的判斷和對(duì)具體產(chǎn)品類型的判斷交錯(cuò)在一起呼股,很難避免模塊功能的蔓延耕魄,對(duì)系統(tǒng)的維護(hù)和擴(kuò)展非常不利画恰;
10. 模板方法模式
實(shí)現(xiàn)方式:
a)?????父類模板類(規(guī)定要執(zhí)行的方法和順序彭谁,只關(guān)心方法的定義及順序,不關(guān)心方法實(shí)現(xiàn))
b)?????子類實(shí)現(xiàn)類(實(shí)現(xiàn)a規(guī)定要執(zhí)行的方法允扇,只關(guān)心方法實(shí)現(xiàn)缠局,不關(guān)心調(diào)用順序)
?優(yōu)點(diǎn):
??????? 1)封裝不變部分,擴(kuò)展可變部分:把認(rèn)為不變部分的算法封裝到父類實(shí)現(xiàn)考润,可變部分則可以通過繼承來(lái)實(shí)現(xiàn)狭园,很容易擴(kuò)展。
??????? 2)提取公共部分代碼糊治,便于維護(hù)唱矛。
???????3)行為由父類控制,由子類實(shí)現(xiàn)。
?缺點(diǎn):
??????? 模板方法模式顛倒了我們平常的設(shè)計(jì)習(xí)慣:抽象類負(fù)責(zé)聲明最抽象绎谦、最一般的事物屬性和方法管闷,實(shí)現(xiàn)類實(shí)現(xiàn)具體的事物屬性和方法。在復(fù)雜的項(xiàng)目中可能會(huì)帶來(lái)代碼閱讀的難度窃肠。