版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
OBSERVER(觀察者)-對(duì)象行為型模式1.意圖定義對(duì)象間的一種一對(duì)多的依賴關(guān)系,當(dāng)一個(gè)對(duì)象的狀態(tài)發(fā)生改變時(shí),所有依賴于它的對(duì)象都得到通知并被自動(dòng)更新。2.別名依賴(Dependents),發(fā)布-訂閱(Publis-Subscribe)3.動(dòng)機(jī)當(dāng)前環(huán)境中有如圖所示的三個(gè)不同的顯示項(xiàng)。用戶也可以獲取天氣狀態(tài)和預(yù)報(bào)。
我們需要?jiǎng)?chuàng)建一個(gè)應(yīng)用程序,可以根據(jù)天氣數(shù)據(jù)對(duì)象來(lái)更新當(dāng)前狀況、氣象統(tǒng)計(jì)以及天氣預(yù)報(bào)的三個(gè)布告板。
這三個(gè)方法分別返回最近的天氣測(cè)量值,包括氣溫、濕度和氣壓值。我們不必關(guān)心這些變量是怎么設(shè)置的,對(duì)象WeatherData知道如何從氣象站獲取更新的信息。我們的工作是,實(shí)現(xiàn)measurementChanged()方法,使之可以更新當(dāng)前狀況、氣象統(tǒng)計(jì)以及天氣預(yù)報(bào)的三個(gè)值。WeatherData類中有三個(gè)獲取測(cè)量值的方法,分別用以獲取溫度、濕度以及氣壓;getTemperature()getHumidity()getPressure()當(dāng)有新的測(cè)量值生效時(shí)可以調(diào)用measurementsChanged()方法。(我們不必知道或者關(guān)心這個(gè)方法是如何被調(diào)用的,只需要知道有這個(gè)方法即可。)
我們需要實(shí)現(xiàn)三個(gè)天氣數(shù)據(jù)的顯示功能:平均溫度:22°最低溫度:16°最高溫度:28°目前狀況溫度:25°濕度:60氣壓:天氣預(yù)報(bào)系統(tǒng)必須具備擴(kuò)展性----其他開發(fā)人員可以創(chuàng)建新的自定義的顯示,用戶根據(jù)需要可以增加或者刪除顯示功能。
?第一次實(shí)現(xiàn)……:在Weather-O-Rama的開發(fā)人員的指導(dǎo)下在measurementsChanged()方法中加入了我們自己的代碼。
通過(guò)調(diào)用getTemperature(),getHumidity(),getPressure()(這三個(gè)方法已經(jīng)被實(shí)現(xiàn)了)獲取最近的天氣數(shù)據(jù)。更新這些顯示的功能:調(diào)用每一個(gè)顯示的功能來(lái)更新其顯示項(xiàng)(最新的天氣數(shù)據(jù))我們的實(shí)現(xiàn)有什么問(wèn)題嗎?A.面向?qū)崿F(xiàn)在編程,而不是面向接口;B.任意一個(gè)新的顯示功能要求,我們必須修改代碼;C.我們無(wú)法在運(yùn)行時(shí)增加(或者刪除)顯示的功能;D.顯示功能沒(méi)有通用的接口;E.對(duì)于容易變化的部分我們沒(méi)有實(shí)現(xiàn)封裝;F.對(duì)于WeatherData類來(lái)說(shuō),我們違背了類的開-閉原則(我們?cè)赪eatherData類里加入了新的代碼,使得WeatherData類發(fā)生了改變)。
在此處我們是用代碼具體實(shí)現(xiàn)了Display功能,將來(lái)我們?nèi)绻朐黾踊蛘邉h除Display功能將變得很困難,除非我們又來(lái)修改這些代碼。從分析來(lái)看,這些地方是屬于容易變化的部分,我們應(yīng)該把這些部分封裝起來(lái),使得由于這些變動(dòng)而不會(huì)改變?cè)械拇a。這里的實(shí)現(xiàn)看起來(lái)我們似乎已經(jīng)使用了一個(gè)通用的接口來(lái)告訴Display功能?它們都有一個(gè)update()方法來(lái)獲取temp,humidity,和Pressure的值。很顯然,系統(tǒng)的維護(hù)性很不好。
觀察者模式的構(gòu)成:Publishers(發(fā)行者)+Subscribers(訂閱者)
=ObserverPattern(觀察者模式)
一對(duì)多當(dāng)主題內(nèi)的數(shù)據(jù)改變,就會(huì)通知觀察者依賴的對(duì)象(Observer依賴于Subject,當(dāng)Subject的數(shù)據(jù)或者狀態(tài)發(fā)聲改變時(shí),Observer可以自動(dòng)得到通知和更新。)Observer模式描述了如何建立這種關(guān)系。這一描述中的關(guān)鍵對(duì)象是目標(biāo)(subject)和觀察者(observer)。一個(gè)目標(biāo)可以有任意數(shù)目的依賴它的觀察者。一旦目標(biāo)的狀態(tài)發(fā)生改變,所有的觀察者都得到通知。作為對(duì)這個(gè)通知的響應(yīng),每個(gè)觀察者都將查詢目標(biāo)以使其狀態(tài)與目標(biāo)的狀態(tài)同步。這種交互也稱為發(fā)布-訂閱。目標(biāo)是通知的發(fā)布者。它發(fā)出通知時(shí)并不需要知道誰(shuí)是它的觀察者??梢杂腥我鈹?shù)目的觀察者訂閱并接收通知。4.適用性在以下任一情況下可以使用觀察者描述:當(dāng)一個(gè)抽象模型有兩個(gè)方面,其中一個(gè)方面依賴于另一方面。將這二者封裝在獨(dú)立的對(duì)象中以使它們可以各自獨(dú)立的改變和復(fù)用。當(dāng)對(duì)一個(gè)對(duì)象的改變需要同時(shí)改變其他對(duì)象,而不知道具體有多少對(duì)象有待改變。當(dāng)一個(gè)對(duì)象必須通知其他對(duì)象,而它又不能假定其他對(duì)象是誰(shuí)。換言之,你不希望這些對(duì)象是緊密耦合的。5.結(jié)構(gòu)6.參與者Subject(目標(biāo)):目標(biāo)知道它的觀察者??梢杂腥我舛嗟挠^察者觀察同一個(gè)目標(biāo);提供注冊(cè)和刪除觀察者對(duì)象的接口。Observer(觀察者):為那些在目標(biāo)發(fā)生改變時(shí)需獲得通知的對(duì)象定義一個(gè)更新接口。ConcreteSubject(具體目標(biāo)):將有關(guān)狀態(tài)存入各自ConcreteObserver對(duì)象;當(dāng)它的狀態(tài)發(fā)生改變時(shí),向它的各個(gè)觀察者發(fā)出通知。ConcreteObserver(具體觀察者):維護(hù)一個(gè)指向ConcreteSubject對(duì)象的引用;存儲(chǔ)有關(guān)狀態(tài),這些狀態(tài)應(yīng)與目標(biāo)的狀態(tài)保持一致;實(shí)現(xiàn)Observer的更新接口以使自身狀態(tài)與目標(biāo)的狀態(tài)保持一致。模式代碼原型staticvoidMain()
{
//ConfigureObserverpattern
ConcreteSubjects=newConcreteSubject();
s.Attach(newConcreteObserver(s,"X"));
s.Attach(newConcreteObserver(s,"Y"));
s.Attach(newConcreteObserver(s,"Z"));
//Changesubjectandnotifyobservers
s.SubjectState="ABC";
s.Notify();
//Waitforuser
Console.ReadKey();
}OutputObserverX'snewstateisABC
ObserverY'snewstateisABC
ObserverZ'snewstateisABCabstractclassSubject
{
privateList<Observer>_observers=newList<Observer>();
publicvoidAttach(Observerobserver)
{
_observers.Add(observer);
}
publicvoidDetach(Observerobserver)
{
_observers.Remove(observer);
}
publicvoidNotify()
{
foreach(Observeroin_observers)
{
o.Update();
}
}
}classConcreteSubject:Subject
{
privatestring_subjectState;
//Getsorsetssubjectstate
publicstringSubjectState
{
get{return_subjectState;}
set{_subjectState=value;}
}
}abstractclassObserver
{
publicabstractvoidUpdate();
}classConcreteObserver:Observer
{
privatestring_name;
privatestring_observerState;
privateConcreteSubject_subject;
//Constructor
publicConcreteObserver(
ConcreteSubjectsubject,stringname)
{
this._subject=subject;
this._name=name;
}
publicoverridevoidUpdate()
{
_observerState=_subject.SubjectState;
Console.WriteLine("Observer{0}'snewstateis{1}",
_name,observerState);
}
//Getsorsetssubject
publicConcreteSubjectSubject
{
get{return_subject;}
set{_subject=value;}
}
}7.協(xié)作當(dāng)ConcreteSubject發(fā)生任何可能導(dǎo)致其觀察者與其自身狀態(tài)不一致的改變時(shí),它將通知它的各個(gè)觀察者。在得到一個(gè)具體目標(biāo)的改變通知后,ConcreteObserver對(duì)象可向目標(biāo)對(duì)象查詢信息。ConcreteObserver使用這些信息以使它的狀態(tài)與目標(biāo)對(duì)象的狀態(tài)一致。8.效果Observer描述允許你獨(dú)立的改變目標(biāo)和觀察者。你可以單獨(dú)復(fù)用目標(biāo)對(duì)象而無(wú)需同時(shí)復(fù)用其觀察者,反之亦然。它也使你可以在不該點(diǎn)目標(biāo)和其他的觀察者的前提下增加觀察者。下面是觀察者描述其他一些優(yōu)缺點(diǎn):1.目標(biāo)和觀察者間的抽象耦合。2.支持廣播通信3.意外的更新9.實(shí)現(xiàn)1.創(chuàng)建目標(biāo)到其觀察者之間的映射。2.觀察多個(gè)目標(biāo)。3.誰(shuí)觸發(fā)更新4.對(duì)已刪除目標(biāo)的懸掛引用5.在發(fā)出通知前確保目標(biāo)的狀態(tài)自身是一致的6.避免特定于觀察者的更新協(xié)議-推/拉模型7.顯式的指定感興趣的改變8.封裝復(fù)雜的更新語(yǔ)義9.結(jié)合目標(biāo)類和觀察者類10.代碼示例見文檔。11.使用Java內(nèi)置的觀察者模式:
java.util包內(nèi)包含最基本的Observer接口與Observable類;這和我們的Subject接口與Observer接口很相似。Observer接口與Observable類使用上更方便,因?yàn)樵S多功能都已經(jīng)事先準(zhǔn)備好了。有了Java內(nèi)置的支持,你只需要擴(kuò)展(繼承)Observable,并告訴它何時(shí)該通知觀察者,一切就完成了,剩下的事API會(huì)幫你做。
Java內(nèi)置的觀察者模式如何運(yùn)作:將對(duì)象變成觀察者:實(shí)現(xiàn)觀察者接口(java.util.Observer),然后調(diào)用任何Observable對(duì)象的addObserver()方法。不想再當(dāng)觀察者時(shí),調(diào)用deleteObserver().可觀察者送出通知:利用擴(kuò)展java.util.Observable接口產(chǎn)生“可觀察者類”先調(diào)用setChanged()方法,標(biāo)記狀態(tài)已經(jīng)改變的事實(shí);調(diào)用兩種notifyObservers()方法中的一個(gè)notifyObservers()notifyObervers(Objectarg)觀察者接收通知:update(Observableo,Objectarg)主題本身當(dāng)作第一個(gè)變量,好讓觀察者知道是哪個(gè)主題通知它的;數(shù)據(jù)對(duì)象作為第二個(gè)變量setChanged(){changed=true}notifyObservers(Objectarg){if(changed){foreveryobserveronthelist{callupdate(this,arg)}changed=false
溫馨提示
- 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 《域名品牌保護(hù)介紹》課件
- 《吆喝課件》課件
- 電力電工基礎(chǔ)習(xí)題庫(kù)含答案
- 養(yǎng)老院老人生活設(shè)施管理制度
- 養(yǎng)老院老人財(cái)產(chǎn)保管制度
- 《皮內(nèi)針刺法》課件
- 旅客運(yùn)輸合同(2篇)
- 2024全新生物制品檢測(cè)與質(zhì)量保證合同2篇
- 電器課件-交流發(fā)電機(jī)
- 2025年廣東貨運(yùn)從業(yè)資格仿真考題
- DB2101T 0108-2024 工程建設(shè)招標(biāo)代理機(jī)構(gòu)公共信用綜合評(píng)價(jià)規(guī)范
- Python課程第二階段第十三課:列表元素的查找和刪除-Python教學(xué)設(shè)計(jì)
- 學(xué)術(shù)研究倫理審查申請(qǐng)范本
- 中國(guó)紅色文化精神智慧樹知到答案2024年西安交通大學(xué)
- 醫(yī)院門診排班與號(hào)源管理制度
- 智能算力數(shù)據(jù)中心安全性與數(shù)據(jù)隱私保護(hù)分析
- 2022-2023學(xué)年貴陽(yáng)市數(shù)學(xué)九年級(jí)第一學(xué)期期末聯(lián)考試題含解析
- 涼山彝族自治州2022-2023學(xué)年七年級(jí)上學(xué)期期末地理試題
- 2025年日歷臺(tái)歷中文版縱向排版帶節(jié)假日調(diào)休周日開始
- 污水處理站操作人員安全培訓(xùn)手冊(cè)
- 健康管理實(shí)務(wù)考試題+參考答案
評(píng)論
0/150
提交評(píng)論