java设计模式:23种设计模式及其源代码演示实现
java23種設(shè)計(jì)模式及其源代碼演示實(shí)現(xiàn)
博主在CSDN已有三年,之前一直在看貼,受益頗多,不可多得的一個(gè)良好的學(xué)習(xí)平臺(tái),這一次,博主給大家分享一份傳說(shuō)中的java設(shè)計(jì)模式,源代碼與其實(shí)現(xiàn)全部都有,希望有助于大家提高開(kāi)發(fā)能力
全文代碼全部手敲,不會(huì)存在侵權(quán)問(wèn)題,純?cè)瓌?chuàng)
歡迎轉(zhuǎn)載,但請(qǐng)附明出處
以下請(qǐng)欣賞全文:文字有點(diǎn)多,因?yàn)槭衷敿?xì)
java23種設(shè)計(jì)模式
1、設(shè)計(jì)模式是人們?cè)诿鎸?duì)同類型軟件工程設(shè)計(jì)問(wèn)題所總結(jié)出的一些有用經(jīng)驗(yàn)。模式不是代碼,而是某類問(wèn)題的通用設(shè)計(jì)解決方案
2、4人組Erich Gamma、Richard Helm、Ralph Johnson、John Vlissides總結(jié)寫了《設(shè)計(jì)模式》
3、設(shè)計(jì)模式的優(yōu)點(diǎn)和用途
4、學(xué)習(xí)設(shè)計(jì)模式最好的方式:在你的設(shè)計(jì)和以往的工程里尋找何處可以使用它們
5、設(shè)計(jì)模式的本質(zhì)目的是使軟件工程在維護(hù)性、擴(kuò)展性、變化性、復(fù)雜度方面成O(N)
6、OO是原則,設(shè)計(jì)模式是具體方法、工具
-------------------------------- 特別說(shuō)明,以下案例皆是主類,將代碼down下食用效果更佳! --------------------------------
類圖圖例:
Person1--eat() 代表Person類下面有一個(gè)eat() 方法1--eat(a,b,c) 代表Person類下面有一個(gè)eat方法,帶3個(gè)參數(shù)1__name __代表屬性,Person下面有name屬性-1__name __屬性私有化1--Student Person類下面有Student內(nèi)部類2__name Student類下有name屬性-->1--Student Person類有子類Student,不在同一個(gè)文件2--run() 子類Student有run方法策略模式01
1.分析項(xiàng)目中變化與不變部分
2.多用組合少用繼承;用行為類組合,而不是行為的繼承.更有彈性
案例:鴨子,不同種類的鴨子具有不同的組合行為
策略模式案例
觀察者模式02
1.多對(duì)一的依賴關(guān)系,Subject
2.觀察者注冊(cè),移除,通知
3.java內(nèi)置觀察者,Observable是類不是接口,不能多重繼承,具體如下:
案例:天氣預(yù)報(bào)項(xiàng)目,不同的公告板顯示不同的公告內(nèi)容
觀察者模式案例
java內(nèi)置觀察者案例
傳統(tǒng)模式案例
傳統(tǒng)模式存在問(wèn)題:一個(gè)需求新建一個(gè)變量,擴(kuò)展性差,見(jiàn)傳統(tǒng)模式
裝飾者模式03
裝飾者模式:動(dòng)態(tài)的將新功能附加到對(duì)象上。在對(duì)象功能擴(kuò)展方面,它比繼承更有彈性。
對(duì)于源有的代碼,不進(jìn)行修改,維護(hù)方便
咖啡館訂單項(xiàng)目:傳統(tǒng)面向?qū)ο箝_(kāi)發(fā),超類擴(kuò)展,新調(diào)料,新單品,各自兩兩組合,類爆炸
new 單品() new Milk(order) …
裝飾者模式案例
java內(nèi)置裝飾者案例
單例模式04
有些對(duì)象只需要一個(gè):線程池,緩存,硬件設(shè)備等
如果多個(gè)實(shí)例會(huì)有造成沖突,結(jié)果的不一致性等問(wèn)題
確保類只有一個(gè)實(shí)例,同時(shí)又有全局訪問(wèn)點(diǎn)
構(gòu)造器私有化
多線程問(wèn)題及優(yōu)化
案例:巧克力工廠
單例模式案例
工廠模式05
pizza項(xiàng)目:有準(zhǔn)備,烘焙,切割,打包4個(gè)步驟,要方便pizza品種的擴(kuò)展,便于維護(hù),運(yùn)行同時(shí)也能擴(kuò)展
傳統(tǒng)模式:運(yùn)行時(shí),增加pizza品種,需要修改類,不滿足運(yùn)行同時(shí)擴(kuò)展要求
傳統(tǒng)模式案例
簡(jiǎn)單工廠模式:對(duì)象的實(shí)例化部分提取出來(lái)放入工廠類,滿足了運(yùn)行同時(shí)擴(kuò)展要求
但仍然有些問(wèn)題:店鋪擴(kuò)展,A地一個(gè)工廠 B地一個(gè)工廠…100個(gè)地方需要100個(gè)工廠,每個(gè)工廠的pizza種類文化均不同
簡(jiǎn)單工廠模式案例
工廠方法模式設(shè)計(jì)方案:將pizza項(xiàng)目里的pizza對(duì)象實(shí)例化功能抽象成抽象方法,在不同加盟店具體實(shí)現(xiàn)功能
工廠方法模式案例
抽象工廠模式:定義了一個(gè)接口用于創(chuàng)建相關(guān)或有依賴關(guān)系的對(duì)象族,而無(wú)需明確指定具體類
工廠抽象成接口,指定工廠接入,子工廠與工廠無(wú)需在類里面直接修改代碼增加變量,代碼復(fù)用極高
依賴抽象原則:
1.變量不要持有具體類的引用
2.不要讓類繼承自具體類,要繼承自抽象類或接口
3.不要覆蓋基類中已實(shí)現(xiàn)的方法
抽象工廠模式案例
命令模式06
家電自動(dòng)化遙控器API項(xiàng)目:背景:一個(gè)遙控器兩排按鈕,如圖示:
● ○
● ○
● ○
● ○
● ○
左邊●這一豎排自上而下分別控制燈,音響,增加音量…
右邊○這一豎排自上而下分別控制關(guān)燈,關(guān)閉音響,減小音量…
要求自動(dòng)化遙控器:擴(kuò)展性好(當(dāng)有新設(shè)備進(jìn)來(lái):掃地機(jī)器人,也接入該遙控器,要求極少量修改遙控器代碼),維護(hù)性好
傳統(tǒng)模式方案問(wèn)題:當(dāng)新設(shè)備進(jìn)來(lái),代碼耦合度極高,維護(hù)困難
傳統(tǒng)模式案例
傳統(tǒng)模式存在的問(wèn)題
命令模式:將請(qǐng)求,命令,動(dòng)作等封裝成對(duì)象,這樣可以讓項(xiàng)目使用這些對(duì)象來(lái)參數(shù)化其他對(duì)象.使得命令的請(qǐng)求者和執(zhí)行者解耦
命令模式案例
宏命令,即一鍵功能
適配器模式07
插頭與插座,汽車點(diǎn)煙器轉(zhuǎn)usb充電器
火雞冒充鴨子項(xiàng)目
背景:火雞類,叫聲AAA飛行:BBB 鴨子類叫聲YYY,飛行FFF.調(diào)用適配器,使得某只火雞調(diào)用適配器接口之后發(fā)出YYY叫聲和FFF飛行
適配器模式:將一個(gè)類的接口轉(zhuǎn)換成另一種接口,讓原本接口不兼容的類可以兼容
從用戶的角度看不到被適配者,是解耦的
用戶調(diào)用適配器轉(zhuǎn)化出來(lái)的目標(biāo)接口方法
適配器調(diào)用被適配者的相關(guān)接口方法
類適配器:通過(guò)多重繼承目標(biāo)接口和被適配者類方式實(shí)現(xiàn)適配
目標(biāo)
↖
適配器
↙
被適配者
多重繼承,其中繼承的目標(biāo)接口部分達(dá)到適配目的,而繼承被適配者類的部分達(dá)到通過(guò)調(diào)用被適配者類里的方法實(shí)現(xiàn)目標(biāo)接口的功能
對(duì)象適配器和類適配器使用了不同的方法實(shí)現(xiàn)適配,對(duì)象適配器使用組合,類適配器使用繼承
適配器模式案例
低版本java枚舉器與高版本java迭代器適配案例
外觀模式08
家庭影院項(xiàng)目:
如下案例,現(xiàn)在要看電影:步驟為,打開(kāi)爆米花機(jī)->打開(kāi)投影儀->放下屏幕->放好CD->拿爆米花->關(guān)閉爆米花機(jī)…
對(duì)象與對(duì)象之間沒(méi)有關(guān)聯(lián),但必須同步方可進(jìn)行事務(wù)
如果每一個(gè)設(shè)備都有各自的按鈕,操作過(guò)程將極其繁瑣
為此,引出外觀模式:提供一個(gè)統(tǒng)一的接口,來(lái)訪問(wèn)子系統(tǒng)中一群功能相關(guān)接口
其定義了一個(gè)高層接口,讓子系統(tǒng)更容易使用
與命令模式的區(qū)別:側(cè)重點(diǎn)不一樣:命令模式,將命令封裝成對(duì)象,外觀模式,將子系統(tǒng)功能暴露成為一個(gè)接口
外觀模式案例
最少知識(shí)原則:盡量減少對(duì)象之間的交互,只留幾個(gè)關(guān)系密切的對(duì)象,項(xiàng)目設(shè)計(jì)中不要讓太多的類耦合在一起
如何遵循:1.對(duì)象方法調(diào)用范圍,調(diào)用自己,作為參數(shù)傳進(jìn)來(lái)的對(duì)象,此方法創(chuàng)建合實(shí)例化的對(duì)象,對(duì)象的組件但方法返回值例外
最少知識(shí)原則Demo
模板模式09
咖啡和泡茶算法:
模板模式:封裝了一個(gè)算法步驟,并允許子類為一個(gè)或多個(gè)步驟方法提供實(shí)現(xiàn)
模板模式可以使子類在不改變算法結(jié)構(gòu)的情況下,重新定義算法中的某些步驟
鉤子函數(shù):超類里面定義,子類重寫,若不重寫,則調(diào)用鉤子函數(shù),若重寫,調(diào)用子類重寫的函數(shù),實(shí)現(xiàn)各自功能
抽取完全相同的功能到超類案例
部分子類實(shí)現(xiàn)不同的功能案例
通用模板模式案例
好萊塢原則:別調(diào)用我們,我們會(huì)調(diào)用你. 高層無(wú)需知道調(diào)用底層細(xì)節(jié),解耦
擴(kuò)展性能和維護(hù)性能提高
與策略模式的差異:模板封裝步驟,策略模式針對(duì)行為等功能進(jìn)行組合,如鴨子會(huì)飛,會(huì)叫,會(huì)用一個(gè)接口對(duì)其進(jìn)行組合.而模板模式:會(huì)叫之后再會(huì)飛,抽象方法,子類進(jìn)行實(shí)現(xiàn)
迭代器模式10
餐廳菜單合并項(xiàng)目:有兩個(gè)餐廳,蛋糕餐廳使用ArrayList維護(hù)菜單,中餐廳使用數(shù)組維護(hù)菜單,現(xiàn)兩個(gè)餐廳需要合并為一個(gè)餐廳,菜單如何維護(hù)?
傳統(tǒng)方案:每個(gè)餐廳自己的菜單,暴露出來(lái)給外部使用
存在問(wèn)題:
1.擴(kuò)展性能差,未來(lái)業(yè)務(wù)擴(kuò)大,新增一個(gè)餐廳合并,該餐廳使用Hash表維護(hù)菜單,則必須新增類,暴露該hash菜單
2.耦合度增加:案例中女招待類打印菜單方法使用了暴露的菜單,所以該方法必須修改
詳:
傳統(tǒng)模式案例
迭代器模式:提供一種方法順序訪問(wèn)一個(gè)聚合對(duì)象中的各個(gè)對(duì)象
1.使用迭代器模式,餐廳的增加不影響Waitress類的修改,解耦
2.餐廳未來(lái)修改菜單個(gè)數(shù),僅需三方服務(wù)商修改其內(nèi)部源碼,直接調(diào)用迭代器接口即可,維護(hù)性強(qiáng)
迭代器模式案例
java內(nèi)置迭代器:數(shù)組沒(méi)有迭代器,自行實(shí)現(xiàn).ArrayList有自己的迭代器,直接使用
現(xiàn)有一使用hash表管理菜單的咖啡館合并入兩家餐館,使用java內(nèi)置迭代器實(shí)現(xiàn)以上項(xiàng)目,詳:
java內(nèi)置迭代器
單一責(zé)任原則:一個(gè)類應(yīng)該只有一個(gè)引起變化的原因
組合模式11
餐館增加新需求:給菜單某一項(xiàng)添加子菜單
組合模式:將對(duì)象聚合成樹形結(jié)構(gòu)來(lái)表現(xiàn)"整體/部分"的層次結(jié)構(gòu)
組合模式能讓客戶以一致的方式來(lái)處理個(gè)別對(duì)象(菜單項(xiàng))以及對(duì)象組合(子菜單),忽略對(duì)象組合與>個(gè)體對(duì)象之間的差別
總結(jié):餐廳合并之后,菜單含子菜單,總體菜單項(xiàng)如何進(jìn)行遍歷??
1.數(shù)據(jù)結(jié)構(gòu)不一樣如何放一起?
2.樹形節(jié)點(diǎn)結(jié)構(gòu)進(jìn)行統(tǒng)一遍歷
3.菜單,子菜單,菜單項(xiàng)目全部繼承一個(gè)超類,即組合模式,整體和局部區(qū)別通過(guò)超類抹去,解耦,屏蔽內(nèi)部實(shí)現(xiàn)
4.遍歷:使用組合迭代器,巧妙利用堆棧遍歷,獲取菜單的同時(shí)又獲取其迭代器,深層遍歷
具體案例如下:
組合模式案例
狀態(tài)模式12
項(xiàng)目:智能糖果機(jī),用Java軟件控制糖果機(jī):待機(jī),投入一元硬幣,轉(zhuǎn)動(dòng)把手,滑落一顆糖果,
待機(jī)(根據(jù)機(jī)器內(nèi)糖果庫(kù)存情況,是否提示售罄)
糖果機(jī)根據(jù)狀態(tài)的不同,行為結(jié)果就不同(如,沒(méi)有塞入硬幣轉(zhuǎn)動(dòng)把手不掉糖果一種結(jié)果和塞入硬幣轉(zhuǎn)動(dòng)把手掉出糖果一種結(jié)果)
傳統(tǒng)設(shè)計(jì)方案:一個(gè)狀態(tài)對(duì)應(yīng)一個(gè)動(dòng)作,采用switch case 強(qiáng)行進(jìn)行功能實(shí)現(xiàn)
則,如果公司增加新需求,加入游戲元素:有10%的概率可以拿到2粒糖果
1.增加一個(gè)新?tīng)顟B(tài)贏家狀態(tài),每一個(gè)動(dòng)作的所有switch均要修改,修改開(kāi)放,耦合大,維護(hù)難
2.基于接口開(kāi)發(fā),不應(yīng)基于功能開(kāi)發(fā)
傳統(tǒng)模式案例
對(duì)于新需求,引入狀態(tài)模式,如下:
糖果機(jī)項(xiàng)目,狀態(tài)和動(dòng)作之間的關(guān)系可以形成如下表格
insertCoin returnCoin turnCrank dispense OnReadyStateHasCoinSoldStateSoldOutStateWinnerState(新增需求,贏家狀態(tài))面向接口進(jìn)行開(kāi)發(fā),所有狀態(tài)抽象成一個(gè)狀態(tài)接口
類結(jié)構(gòu)如下
狀態(tài)模式:根據(jù)內(nèi)部狀態(tài)的變化,改變對(duì)象的行為,看起來(lái)似乎修改了類
狀態(tài)模式案例
策略模式一般情況下可以作為狀態(tài)模式的基礎(chǔ),模板模式:部分拼接形成一個(gè)整體,狀態(tài)模式:每一個(gè)狀態(tài)都是整體
代理模式13
糖果機(jī)監(jiān)控項(xiàng)目:你是公司上市老板:需要知道各個(gè)地方的糖果機(jī)運(yùn)行情況,監(jiān)控運(yùn)行
首先,本地糖果機(jī)監(jiān)控,只需要設(shè)計(jì)一個(gè)監(jiān)控類,類里面放糖果機(jī)集合,實(shí)現(xiàn)監(jiān)控情況即可,具體案例如下:
本地監(jiān)控糖果機(jī)案例
好,現(xiàn)公司壯大,糖果賣得火爆,為進(jìn)行市場(chǎng)分析,需要進(jìn)行遠(yuǎn)程監(jiān)控糖果機(jī),如何實(shí)現(xiàn)?
由此引入代理監(jiān)控方案–遠(yuǎn)程代理:遠(yuǎn)程對(duì)象(如其他地方糖果機(jī))的本地代表(該糖果機(jī)的代表對(duì)象),通過(guò)它可以讓遠(yuǎn)程對(duì)象當(dāng)本地對(duì)象來(lái)調(diào)用
遠(yuǎn)程代理通過(guò)網(wǎng)絡(luò)和真正的遠(yuǎn)程對(duì)象溝通信息:
代理模式原理:為一個(gè)對(duì)象提供一個(gè)替身,控制對(duì)這個(gè)對(duì)象的訪問(wèn)
Java RMI:計(jì)算機(jī)之間通過(guò)網(wǎng)絡(luò)實(shí)現(xiàn)對(duì)象調(diào)用的一種通訊機(jī)制
該機(jī)制可以讓一臺(tái)計(jì)算機(jī)上的對(duì)象可以調(diào)用另外一臺(tái)計(jì)算機(jī)上的對(duì)象來(lái)獲取遠(yuǎn)程數(shù)據(jù)
Java RMI 案例如下:
RMIHelloWord服務(wù)端
RMIHelloWord客戶端
糖果機(jī)項(xiàng)目RMI服務(wù)端
糖果機(jī)項(xiàng)目RMI客戶端
#####幾種常見(jiàn)代理模式
虛擬代理:虛擬代理為創(chuàng)建開(kāi)銷大的對(duì)象提供代理服務(wù),真正的對(duì)象在創(chuàng)建前和創(chuàng)建中時(shí),由虛擬代理扮演替身,如:瀏覽網(wǎng)頁(yè)在線圖片加載
動(dòng)態(tài)代理:運(yùn)行時(shí)動(dòng)態(tài)的創(chuàng)建代理類對(duì)象,并將方法調(diào)用轉(zhuǎn)發(fā)到指定類
保護(hù)代理:看一個(gè)找對(duì)象項(xiàng)目,個(gè)人信息,興趣愛(ài)好,打分,只可以訪問(wèn)部分等
使用 Proxy 類進(jìn)行代理模式之保護(hù)代理設(shè)計(jì):鏈接如下
權(quán)限設(shè)置保護(hù)代理案例
與裝飾者模式的區(qū)別:裝飾者模式,裝飾之后會(huì)添加新功能;而代理模式是對(duì)目標(biāo)對(duì)象訪問(wèn)的控制和管理
復(fù)合模式14
復(fù)合模式能解決一般性或一系列問(wèn)題
復(fù)雜鴨子項(xiàng)目:
多種鴨子,不同鴨子叫聲,飛行,游泳方式不同–策略模式
鵝,需要加入幾只普通的鵝–適配器模式(用鴨子模擬鵝)
要統(tǒng)計(jì)鴨子叫聲的次數(shù)–裝飾者模式(動(dòng)態(tài)的過(guò)程中增加新功能)
統(tǒng)一產(chǎn)生鴨子–工廠模式
管理一群鴨子–組合模式(迭代器)
追蹤某個(gè)鴨子的行為–觀察者模式(注冊(cè),反注冊(cè),通知)
MVC:模式與模式進(jìn)行組合
MVC:Model,View,Controller
MVC解決什么類型的項(xiàng)目需求?
為什么采用MVC結(jié)構(gòu)?
–結(jié)構(gòu)復(fù)雜度降低,耦合度降低,不同部分獨(dú)立升級(jí)
Model:程序主體,代表業(yè)務(wù)數(shù)據(jù)和業(yè)務(wù)邏輯
View:是與用戶交互的界面,顯示數(shù)據(jù),接收輸入但不參與實(shí)際業(yè)務(wù)邏輯
Controller:接收用戶輸入,并解析反饋給Model
MVC里的模式:
Model與View和Controller是觀察者模式
View以組合模式管理控件(各種歌曲列表,彈窗等)
View與Controller是策略模式關(guān)系,Controller提供策略
以上很拗口,很難理解,以下作具體分析:
分析一個(gè)播放器軟件 Model 播放器內(nèi)部業(yè)務(wù)__Songs //屬性,歌曲信息列表__State //屬性,狀態(tài)(按鈕狀態(tài),播放狀態(tài),歌曲狀態(tài)等)--start() //播放--pause() //暫停--stop() //停止--next() //下一首--previous() //上一首--getInfo() //獲取歌曲信息View用戶界面顯示屏 按鈕1,按鈕2,按鈕3,按鈕4你好:這是一個(gè)Mp4圖片,請(qǐng)自行想象Controller 策略,行為集,給按鈕增加功能--Button1() --Button2()--Button3()--Button4()模擬:用戶按下了按鈕3,想要切換下一首歌1.通過(guò)Controller解析出來(lái)該按鈕的功能為切換下一首歌曲2.調(diào)用業(yè)務(wù)邏輯,Model.next()方法被調(diào)用,采用觀察者模式通知View,信息變了,View采取相應(yīng)措施3.歌曲播放完畢,Model觀察者通知View歌曲結(jié)束,View相應(yīng)進(jìn)行響應(yīng),比如彈出一個(gè)窗口,歌曲播放完畢或者自動(dòng)播放下一首歌等4.3這個(gè)也可以讓Model通知Controller,具體業(yè)務(wù)具體分析Android App就是一個(gè)很典型的例子–>
生命周期–模板模式
整體上是MVC
電池電量,觀察者
列表,模板
橋接模式15
橋接目的,分離抽象與實(shí)現(xiàn),使抽象和實(shí)現(xiàn)可以獨(dú)立變化
系統(tǒng)多維度角度分類,而每一種分類又有可能變化,考慮使用橋接模式
遙控器項(xiàng)目:索尼公司遙控器,廠家提供接口,遙控器調(diào)用接口實(shí)現(xiàn)遙控各種家電
極簡(jiǎn)設(shè)計(jì)方案:類圖如下:
極簡(jiǎn)設(shè)計(jì)方案
該方案存在問(wèn)題:新需求帶來(lái)的設(shè)計(jì)問(wèn)題,電視機(jī)廠家,新功能的遙控器出來(lái),則新遙控器重新繼承每一個(gè)類,類爆炸
橋接模式:將實(shí)現(xiàn)與抽象放在兩個(gè)不同的類層次重,使兩個(gè)層次可以獨(dú)立改變
類圖如下:
橋接模式案例
生成器模式16
生成器模式:
將復(fù)雜對(duì)象創(chuàng)建過(guò)程封裝
隱藏類的內(nèi)部結(jié)構(gòu)
允許對(duì)象通過(guò)幾個(gè)步驟創(chuàng)建,并且可以改變工程(工廠模式只有一個(gè)步驟)
度假計(jì)劃項(xiàng)目:有3天度假計(jì)劃,4天度假計(jì)劃(每個(gè)計(jì)劃都是不同對(duì)象),如何生成?使用生成器模式:
生成器模式:封裝一個(gè)復(fù)雜對(duì)象構(gòu)造過(guò)程,并允許按步驟構(gòu)造
具體案例:生成器模式案例
省略抽象生成器類
省略指導(dǎo)者類
與抽象工廠的差異:主要用于創(chuàng)建復(fù)雜,大的對(duì)象
責(zé)任鏈模式17
購(gòu)買請(qǐng)求決策項(xiàng)目:決策因素:價(jià)格
決策級(jí)別:組長(zhǎng),部長(zhǎng),副總,總裁
考慮擴(kuò)展性
如果多個(gè)對(duì)象都有機(jī)會(huì)處理請(qǐng)求,責(zé)任鏈可使請(qǐng)求的發(fā)送者和接受者解耦,請(qǐng)求沿著責(zé)任鏈傳遞,直到有一個(gè)對(duì)象處理了它為止.
該模式簡(jiǎn)化了對(duì)象,因?yàn)闊o(wú)須知道鏈結(jié)構(gòu)
該模式可以動(dòng)態(tài)增加或刪減處理請(qǐng)求的鏈結(jié)構(gòu)
該模式請(qǐng)求從鏈開(kāi)頭進(jìn)行遍歷,對(duì)性能有一定損耗
該模式并不一定保證請(qǐng)求被處理
項(xiàng)目類圖如下:
PurchaseRequest->A類(請(qǐng)求沒(méi)處理,拋!)->B類(請(qǐng)求沒(méi)處理,拋!)->C類(請(qǐng)求沒(méi)處理,拋!)->D類(請(qǐng)求被處理)責(zé)任鏈模式案例
適用于:有多個(gè)對(duì)象可以處理一個(gè)請(qǐng)求,不明確接收者情況
與狀態(tài)模式的差異:責(zé)任鏈,注重請(qǐng)求的傳遞,狀態(tài)模式,注重對(duì)象狀態(tài)的轉(zhuǎn)換
蠅量模式18
景觀設(shè)計(jì)軟件項(xiàng)目:
樹:XY坐標(biāo),樹的大小,外觀,需要很多樹;1000W棵樹,需要對(duì)象Tree 1000W 個(gè),小對(duì)象大量級(jí)的問(wèn)題解決
傳統(tǒng)方案設(shè)計(jì):傳統(tǒng)模式
分析:
Tree1__xCoord1__yCoord1__age1--display() 1000W個(gè)Tree對(duì)象實(shí)在太多,影響性能,該如何做?引入蠅量模式TreeManager1__xArray1__yArray1__AgeArray1--displayTrees()Tree1--display()蠅量模式案例1
蠅量模式:通過(guò)共享的方式高效地支持大量細(xì)粒度的對(duì)象,適用于大量細(xì)粒度對(duì)象(上千萬(wàn)),且這些對(duì)象的外部狀態(tài)不多
優(yōu)缺點(diǎn)分析:
優(yōu)點(diǎn):
–減少運(yùn)行時(shí)對(duì)象實(shí)例個(gè)數(shù),節(jié)省創(chuàng)建開(kāi)銷和內(nèi)存
–許多虛擬對(duì)象狀態(tài)集中管理
缺點(diǎn):
–系統(tǒng)設(shè)計(jì)更加復(fù)雜
–專門維護(hù)對(duì)象外部狀態(tài)
項(xiàng)目有新需求:增加一些草 類圖如下:
PlantFactory1--getPlant() (PlantManager、Plant類通過(guò)該方法顯示具體結(jié)果)PlantManager1__xArray1__yArray1__AgeArray1__typeArray1--displayTrees() -> Plant.display()<abstract> Plant1--display()-->1\\Grass2--display()-->1\\Tree2--display()如何才能實(shí)現(xiàn)內(nèi)存最佳化利用??
引入草對(duì)象按蠅量模式設(shè)計(jì)案例2
解釋器模式19
大數(shù)據(jù)統(tǒng)計(jì)項(xiàng)目:按照計(jì)算模型對(duì)現(xiàn)有數(shù)據(jù)統(tǒng)計(jì),分析,預(yù)測(cè),計(jì)算模型需要運(yùn)行期編輯,如何設(shè)計(jì)??寫函數(shù),寫sql?
最好能有一個(gè)通用方案,各部門都能通用,維護(hù)也方便,擴(kuò)展也方便,引入解釋器模式:
解釋器模式:計(jì)算模型按正常算式方式書寫,解釋器處理語(yǔ)法邏輯;定義一個(gè)語(yǔ)法,定義一個(gè)解釋器,該解釋器處理該語(yǔ)法句子
計(jì)算模式里有兩類符號(hào):數(shù)據(jù)和計(jì)算符(±*/語(yǔ)法規(guī)則,優(yōu)先級(jí)等)
逆波蘭算法分析算式語(yǔ)法
用解釋器模式處理數(shù)據(jù)
優(yōu)點(diǎn):
–容易修改,修改語(yǔ)法規(guī)則只要修改相應(yīng)非終結(jié)符即可
–擴(kuò)展方便,擴(kuò)展語(yǔ)法,增加非終結(jié)符類即可
缺點(diǎn):
–復(fù)雜語(yǔ)法,類結(jié)構(gòu)巨復(fù)雜,不便管理和維護(hù),盡量不要在重要的模塊中使用
–采用遞歸方式,效率會(huì)受影響
可以僅作了解:實(shí)際系統(tǒng)開(kāi)發(fā)中使用的非常少
使用場(chǎng)合:數(shù)據(jù)分析工具,報(bào)表設(shè)計(jì)工具,科學(xué)計(jì)算工具
原理類圖如下:將某些復(fù)雜問(wèn)題,表達(dá)為某種語(yǔ)法規(guī)則,然后構(gòu)建解釋器解釋處理這類句子
用戶Client發(fā)出一個(gè)算式Context,定義解釋器: AbstractExpression1--Interpret(Context)-->1\\TerminalExpression 子類2--Interpret(Context)-->1\\NoterminalExpression 子類2--Interpret(Context)回到大數(shù)據(jù)統(tǒng)計(jì)項(xiàng)目,該項(xiàng)目采用解釋器模式進(jìn)行:類圖如下
<abstract> AbstractExpresstion1--Interpret()-->1--VarExpresstion 變量表達(dá)式子類2--Interpret()-->1--SymbolExpresstion 符號(hào)表達(dá)式子類2--Interpret()-->2--AddExpresstion +3--Interpret()-->2--SubExpresstion -3--Interpret()-->2--MutilExpresstion *3--Interpret()-->2--DivExpresstion /3--Interpret()解釋器模式案例
中介者模式20
中介者模式,用一個(gè)中介對(duì)象來(lái)封裝一系列的對(duì)象交互
中介者使各對(duì)象不需要顯式地相互引用,從而使其耦合松散,而且可以獨(dú)立地改變它們之間的交互
優(yōu)點(diǎn):
–彼此解耦對(duì)象,增加對(duì)象復(fù)用
–控制邏輯集中,簡(jiǎn)化系統(tǒng)維護(hù)
–對(duì)象之間傳遞消息變得簡(jiǎn)單而且大幅減少
–提高系統(tǒng)靈活,易于擴(kuò)展和維護(hù)
缺點(diǎn):
–中介是中心,出現(xiàn)問(wèn)題則會(huì)影響整個(gè)系統(tǒng)
–中介者本身對(duì)象可能會(huì)變得過(guò)于復(fù)雜源于設(shè)計(jì)不當(dāng)
智慧房屋項(xiàng)目:公司專業(yè)生產(chǎn)各種房子,房子里有智慧鬧鐘,咖啡機(jī),電視機(jī),窗簾等,實(shí)現(xiàn)以下需求
某一時(shí)刻,鬧鐘響起,咖啡機(jī)自動(dòng)泡咖啡,同時(shí)自動(dòng)打開(kāi)電視機(jī),等待咖啡機(jī)泡咖啡結(jié)束窗簾自動(dòng)落下,房間燈自動(dòng)亮起…
傳統(tǒng)設(shè)計(jì)邏輯:Alarm—1號(hào),TV—2號(hào),CoffeeMachine—3號(hào),Curtains—4號(hào)
1給2,3發(fā)消息,3給2,4發(fā)消息…
對(duì)象之間耦合性過(guò)強(qiáng),擴(kuò)展復(fù)用性能差,維護(hù)難,不好調(diào)試
中介者模式:引入一個(gè)中介,Mediator,對(duì)象之間省去互相溝通,各對(duì)象僅與中介溝通,由中介對(duì)結(jié)果進(jìn)行反饋
邏輯:1–中介,2–中介,3–中介,4–中介,中介–1,2,3,4
中介者模式案例
中介者模式與觀察者模式:觀察者模式廣播,中介者定向
適用場(chǎng)合:一組對(duì)象之間通信方式比較復(fù)雜,導(dǎo)致相互依賴,結(jié)構(gòu)混亂;一個(gè)對(duì)象引用許多其他對(duì)象并直接與這些對(duì)象通信,導(dǎo)致難以復(fù)用該對(duì)象
備忘錄模式21
備忘錄模式:在不破壞封裝的前提下,存儲(chǔ)關(guān)鍵對(duì)象的重要狀態(tài),從而可以把對(duì)象還原到存儲(chǔ)的那個(gè)狀態(tài)
游戲項(xiàng)目:游戲進(jìn)度狀態(tài)保存問(wèn)題.對(duì)象狀態(tài),場(chǎng)景狀態(tài),大型項(xiàng)目,每個(gè)人開(kāi)發(fā)自己的保存功能,這個(gè)效率將十分低
引入備忘錄模式:統(tǒng)一功能,每一個(gè)人開(kāi)發(fā)的保存功能用一個(gè)類進(jìn)行管理,設(shè)計(jì)MemetoIF接口,別人開(kāi)發(fā)的細(xì)節(jié)自己將看不到,保證信息安全
優(yōu)點(diǎn):
–狀態(tài)存儲(chǔ)在外面,不和關(guān)鍵對(duì)象混一起,可以幫助維護(hù)內(nèi)聚
–提供容易實(shí)現(xiàn)的恢復(fù)能力
–保持關(guān)鍵對(duì)象的數(shù)據(jù)封裝
缺點(diǎn):
–資源消耗上面?zhèn)渫泴?duì)象會(huì)很昂貴
–存儲(chǔ)和還原比較耗時(shí)
場(chǎng)合:必須保存一個(gè)對(duì)象在某一個(gè)時(shí)刻的整體或部分狀態(tài),在對(duì)象以外的地方進(jìn)行恢復(fù)
備忘錄模式案例
原型模式22
電子賬單項(xiàng)目:銀行的電子賬單,廣告信,特點(diǎn),量大,時(shí)間要求緊
傳統(tǒng)設(shè)計(jì)模式案例
問(wèn)題來(lái)了:500萬(wàn)用戶發(fā)送郵件,一封郵件0.1s發(fā)出,需要50Ws…6天!
那么解決方案:SendMail多線程并發(fā)進(jìn)行,需要在每一封郵件發(fā)送前新創(chuàng)建對(duì)象,每次new,內(nèi)存資源浪費(fèi)
引入原型模式:一個(gè)對(duì)象,通過(guò)內(nèi)存復(fù)制創(chuàng)建新一模一樣對(duì)象,該對(duì)象指向其他內(nèi)存區(qū)域,無(wú)須知道相應(yīng)類的信息
優(yōu)點(diǎn):
–使用原型模式創(chuàng)建對(duì)象比直接new一個(gè)對(duì)象更有效
–隱藏制造新實(shí)例復(fù)雜性
–重復(fù)創(chuàng)建相似對(duì)象時(shí)可以考慮使用
缺點(diǎn)
–深層復(fù)制比較復(fù)雜
–每一個(gè)類必須配備一個(gè)克隆方法
注意事項(xiàng):
1.使用原型模式復(fù)制對(duì)象不會(huì)調(diào)用類的構(gòu)造方法!!!所以單例模式與原型模式是沖突的
2.final 對(duì)象由于不能改動(dòng)(其內(nèi)存空間固定),故采用原型模式的類無(wú)法使用final聲明的對(duì)象
3.Object類的clone方法只會(huì)拷貝對(duì)象中的基本數(shù)據(jù)類型,對(duì)于數(shù)組,容器,引用對(duì)象等都不會(huì)拷貝,這就是淺拷貝
4.實(shí)現(xiàn)深拷貝必須將原型模式中的數(shù)組,容器對(duì)象,引用對(duì)象等另外拷貝
原型模式案例深拷貝
適用場(chǎng)合:
1.復(fù)制對(duì)象結(jié)構(gòu)和數(shù)據(jù)
2.希望對(duì)目標(biāo)對(duì)象的修改不影響既有的原型對(duì)象
3.創(chuàng)建對(duì)象成本較大的情況下
訪問(wèn)者模式23
雇員管理系統(tǒng)項(xiàng)目:Employee,需要添加一些新的操作功能,具體案例如下:
傳統(tǒng)模式案例 違背開(kāi)閉原則
訪問(wèn)者模式:對(duì)于一群對(duì)象,在不改變數(shù)據(jù)結(jié)構(gòu)的前提下,增加作用于這些結(jié)構(gòu)元素新的功能,適用于數(shù)據(jù)結(jié)構(gòu)相對(duì)穩(wěn)定,
數(shù)據(jù)結(jié)構(gòu)和作用于其上的操作解耦,使得操作集合可以相對(duì)自由地演化
優(yōu)點(diǎn):
1.一個(gè)訪問(wèn)者一個(gè)功能,符合單一職責(zé)原則
2.擴(kuò)展性良好
3.有益于系統(tǒng)的管理和維護(hù)
缺點(diǎn):
1.增加新的元素類變得很困難,修改算法
2.破壞封裝性
訪問(wèn)者模式案例
注意事項(xiàng):
1.系統(tǒng)有比較穩(wěn)定的數(shù)據(jù)結(jié)構(gòu)
2.與迭代器的關(guān)系:迭代器提供訪問(wèn)者注入的一種方式,訪問(wèn)者對(duì)對(duì)象進(jìn)行處理
適用場(chǎng)合:數(shù)據(jù)結(jié)構(gòu)比較穩(wěn)定,需求又經(jīng)常變化,那么訪問(wèn)者模式比較適合
寫在最后:
模式:在某些場(chǎng)景下,針對(duì)某類問(wèn)題的某種通用解決方案,其中,場(chǎng)景是項(xiàng)目環(huán)境,問(wèn)題是約束條件,項(xiàng)目目標(biāo);解決方案:通用可以復(fù)用的設(shè)計(jì),解決約束達(dá)到目標(biāo) (實(shí)際經(jīng)驗(yàn)的總結(jié)) 設(shè)計(jì)模式的三個(gè)分類--創(chuàng)建型模式:對(duì)象實(shí)例化的模式,解耦了對(duì)象的實(shí)例化過(guò)程--結(jié)構(gòu)型模式:把類或?qū)ο蠼Y(jié)合一起形成更大的結(jié)構(gòu)--行為型模式:類和對(duì)象如何交互,及劃分責(zé)任和算法簡(jiǎn)單工廠:一個(gè)工廠類根據(jù)傳入的參量決定創(chuàng)建出哪一種產(chǎn)品類的實(shí)例
工廠方法:定義一個(gè)創(chuàng)建對(duì)象的接口,讓子類決定實(shí)例化哪一個(gè)類
抽象工廠:創(chuàng)建相關(guān)或依賴對(duì)象的家族,而無(wú)需明確指定具體類
單例模式:類只有一個(gè)實(shí)例,提供一個(gè)全局訪問(wèn)點(diǎn)
生成器模式:封裝一個(gè)復(fù)雜對(duì)象的構(gòu)建過(guò)程,可以按步驟構(gòu)造
原型模式:通過(guò)復(fù)制現(xiàn)有的實(shí)例來(lái)創(chuàng)建新的實(shí)例
適配器模式:將一個(gè)類的方法接口轉(zhuǎn)換成客戶希望的另外一個(gè)接口
組合模式:將對(duì)象組合成樹形結(jié)構(gòu)以表示"部分-整體"的層次結(jié)構(gòu)
裝飾模式:動(dòng)態(tài)地給對(duì)象添加新的功能
代理模式:為其他對(duì)象提供一個(gè)代理以控制對(duì)這個(gè)對(duì)象的訪問(wèn)
蠅量模式:通過(guò)共享技術(shù)有效地支持大量細(xì)粒度的對(duì)象
外觀模式:提供統(tǒng)一的方法來(lái)訪問(wèn)子系統(tǒng)的一群接口
橋接模式:將抽象部分與它的實(shí)現(xiàn)部分分離,使它們都可以獨(dú)立地變化
模板模式:定義一個(gè)算法結(jié)構(gòu),而將一些步驟延遲到子類中實(shí)現(xiàn)
解釋器模式:給定一個(gè)語(yǔ)言,定義它的文法的一種表示,并定義一個(gè)解釋器
策略模式:定義一系列的算法,把它們封裝起來(lái),并且使它們可相互替換
狀態(tài)模式:允許一個(gè)對(duì)象在其內(nèi)部狀態(tài)改變時(shí)改變它的行為
觀測(cè)者模式:對(duì)象間的一對(duì)多的依賴關(guān)系
備忘錄模式:在不破壞封裝性的前提下,保存對(duì)象的內(nèi)部狀態(tài)
中介者模式:用一個(gè)中介對(duì)象來(lái)封裝一系列的對(duì)象交互
命令模式:將命令請(qǐng)求封裝為一個(gè)對(duì)象,使得可用不同的請(qǐng)求來(lái)進(jìn)行參數(shù)化
訪問(wèn)者模式:在不改變數(shù)據(jù)結(jié)構(gòu)的前提下,增加作用于一組對(duì)象元素新的功能
責(zé)任鏈:請(qǐng)求發(fā)送者和接收者之間解耦,使得多個(gè)對(duì)象都有機(jī)會(huì)處理這個(gè)請(qǐng)求
迭代器:一種遍歷訪問(wèn)聚合對(duì)象中各個(gè)元素的方法,不暴露該對(duì)象的內(nèi)部結(jié)構(gòu)
對(duì)象設(shè)計(jì)的六大原則:
組合復(fù)用原則:多用組合,少用繼承,找到變化部分,抽象,封裝變化(has A 與 is A).鴨子項(xiàng)目01
依賴倒置原則:
依賴:成員變量,方法參數(shù),返回值,依賴于抽象,不要依賴于具體
高層模塊不應(yīng)該依賴低層,且都應(yīng)該依賴其抽象
具體應(yīng)該依賴抽象,抽象不應(yīng)該依賴具體
針對(duì)接口編程,不要針對(duì)實(shí)現(xiàn)編程
項(xiàng)目架構(gòu):以抽象為基礎(chǔ)搭建
開(kāi)閉原則:對(duì)擴(kuò)展開(kāi)放,對(duì)修改關(guān)閉,通過(guò)擴(kuò)展已有軟件系統(tǒng),提供新功能,對(duì)修改的關(guān)閉,保證穩(wěn)定性和延續(xù)性
里氏替換原則:
引用基類的地方必須能透明地使用其子類對(duì)象
子類擴(kuò)展父類功能,不能破壞父類原有的功能
設(shè)計(jì)繼承,子類可以實(shí)現(xiàn)父類的抽象方法,但不能覆蓋父類的非抽象方法
子類重載父類方法,方法的形參要比父類方法的參數(shù)更寬松
子類實(shí)現(xiàn)父類抽象方法,方法的返回值要比父類更嚴(yán)格
迪米特法則:
一個(gè)對(duì)象應(yīng)該與其他對(duì)象保持最少了解盡量降低類與類之間的耦合
接口隔離原則:一個(gè)類對(duì)另一個(gè)類的依賴應(yīng)該建立在最小的接口上
單一職責(zé)原則:實(shí)際工作中很難達(dá)到,即一個(gè)類只負(fù)責(zé)一項(xiàng)職責(zé)
用模式來(lái)思考:
保持簡(jiǎn)單:
盡可能用最簡(jiǎn)單的方式解決問(wèn)題
設(shè)計(jì)模式非萬(wàn)能:
模式是通用問(wèn)題的經(jīng)驗(yàn)總結(jié)
考慮它對(duì)其他部分影響
不需要預(yù)留任何彈性時(shí),刪除掉模式
何時(shí)需要模式:
設(shè)計(jì)中會(huì)變化的部分,通常就是需要考慮模式的地方
重構(gòu)時(shí),帶進(jìn)模式
重構(gòu)的時(shí)間就是模式的時(shí)間:
利用模式來(lái)重構(gòu)
總結(jié)
以上是生活随笔為你收集整理的java设计模式:23种设计模式及其源代码演示实现的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 核心交换机和普通交换机有何区别?
- 下一篇: 0LL或0x0UL是什么意思?