亚洲免费在线-亚洲免费在线播放-亚洲免费在线观看-亚洲免费在线观看视频-亚洲免费在线看-亚洲免费在线视频

觀察者模式

系統(tǒng) 2733 0
觀察者(Observer)模式 :是對(duì)象的行為模式,又叫做發(fā)布-訂閱(Publish/Subscribe)模式、模型-視圖(Model/View)模式、源-監(jiān)聽(Source/Listener)模式或者從屬(Dependents)模式。觀察者模式定義了一種一對(duì)多的依賴關(guān)系,讓多個(gè)觀察者對(duì)象同時(shí)監(jiān)聽某一個(gè)主題對(duì)象,這個(gè)主題對(duì)象在狀態(tài)上發(fā)生變化時(shí),會(huì)通知所有觀察者對(duì)象,使它們能夠自動(dòng)更新自己。
觀察者模式類的結(jié)構(gòu):
觀察者模式角色如下:
抽象主題(Subject)角色 :抽象主題角色提供維護(hù)一個(gè)觀察者對(duì)象聚集的操作方法,對(duì)聚集的增加、刪除等。
具體主題(ConcreteSubject)角色 :將有關(guān)狀態(tài)存入具體的觀察者對(duì)象;在具體主題的內(nèi)部狀態(tài)改變時(shí),給所有登記過的觀察者發(fā)出通知。具體主題角色負(fù)責(zé)實(shí)現(xiàn)抽象主題中聚集的管理方法。
抽象觀察者(Observer)角色 :為具體觀察者提供一個(gè)更新接口。
具體觀察者(ConcreteObserver)角色 :存儲(chǔ)與主題相關(guān)的自洽狀態(tài),實(shí)現(xiàn)抽象觀察者提供的更新接口。
?
仔細(xì)觀察上面的類圖,發(fā)現(xiàn)具體主題角色和抽象觀察者之間的連線,是因?yàn)榫唧w主題角色維護(hù)了一個(gè)觀察者引用的聚集,如果有多個(gè)具體主題角色,意味著每個(gè)具體角色都要維護(hù)一個(gè)觀察者的聚集,那么能不能將聚集提升到抽象主題里面呢?這個(gè)就需要考慮場(chǎng)景,如果多個(gè)主題實(shí)現(xiàn)在管理上都有很大差異,那么就不能提升到抽象角色中,但是絕大多數(shù)情況下,這些聚集管理方法本身就是所有具體主題所共有的,所以大多數(shù)情況下都是可以將聚集和聚集的管理都移入到抽象主題中的,因?yàn)閚otifyObserver()方法是依賴于聚集的,所以將notifyObserver()也移入抽象主題中,這樣就形成了如下的另一種觀察者模式結(jié)構(gòu):
觀察者模式
? 我們這里簡(jiǎn)單用代碼描述如下:
Java代碼?? 收藏代碼
  1. package ?observer.desc;??
  2. /** ?
  3. ?*? ?
  4. ?*作者:alaric ?
  5. ?*時(shí)間:2013-8-13下午8:05:08 ?
  6. ?*描述:抽象觀察者 ?
  7. ?*/ ??
  8. public ? interface ?Observer?{??
  9. ??????
  10. ???? public ? void ?update();??
  11. ??????
  12. }??
?
Java代碼?? 收藏代碼
  1. package ?observer.desc;??
  2. /** ?
  3. ?*? ?
  4. ?*作者:alaric ?
  5. ?*時(shí)間:2013-8-13下午8:05:34 ?
  6. ?*描述:具體觀察者 ?
  7. ?*/ ??
  8. public ? class ?ConcreteObserver? implements ?Observer{??
  9. ??
  10. ???? @Override ??
  11. ???? public ? void ?update()?{??
  12. ???????? //?寫業(yè)務(wù)邏輯 ??
  13. ????}??
  14. ??
  15. }??
?
Java代碼?? 收藏代碼
  1. package ?observer.desc;??
  2. /** ?
  3. ?*? ?
  4. ?*作者:alaric ?
  5. ?*時(shí)間:2013-8-13下午8:05:55 ?
  6. ?*描述:抽象主題 ?
  7. ?*/ ??
  8. public ? interface ?Subject?{??
  9. ??
  10. ???? public ? void ?attach(Observer?observer);??
  11. ??
  12. ???? public ? void ?detach(Observer?observer);??
  13. ??
  14. ???? void ?notifyObservers();??
  15. }??
?
Java代碼?? 收藏代碼
  1. package ?observer.desc;??
  2. ??
  3. import ?java.util.Enumeration;??
  4. import ?java.util.Vector;??
  5. /** ?
  6. ?*? ?
  7. ?*作者:alaric ?
  8. ?*時(shí)間:2013-8-13下午8:09:21 ?
  9. ?*描述:具體主題類 ?
  10. ?*/ ??
  11. public ? class ?ConcreteSubject? implements ?Subject?{??
  12. ???? private ?Vector<Observer>observersVector?=? new ?Vector<Observer>();??
  13. ???? public ? void ?attach(Observer?observer)?{??
  14. ????????observersVector.addElement(observer);??
  15. ????}??
  16. ??
  17. ???? public ? void ?detach(Observer?observer)?{??
  18. ????????observersVector.removeElement(observer);??
  19. ????}??
  20. ??
  21. ???? public ? void ?notifyObservers()?{??
  22. ????????Enumeration<Observer>enumeration?=?observers();??
  23. ???????? while ?(enumeration.hasMoreElements())?{??
  24. ????????????((Observer)?enumeration.nextElement()).update();??
  25. ????????}??
  26. ????}??
  27. ??
  28. ???? @SuppressWarnings ( "unchecked" )??
  29. ???? public ?Enumeration<Observer>?observers()?{??
  30. ???????? return ?((Vector<Observer>)?observersVector.clone()).elements();??
  31. ????}??
  32. ??
  33. }???
上面代碼描述第一種形式,第二種讀者可以自己實(shí)現(xiàn),這里不再贅述。
接下來我們看java語言是如何支持觀察者模式的,java提供一個(gè)被觀察者類java.util.Observable和一個(gè)觀察者接口java.util.Observer。

jdk1.6中API文檔如下描述:

public interface Observer

一個(gè)可在觀察者要得到 observable 對(duì)象更改通知時(shí)可實(shí)現(xiàn) Observer 接口的類。

從以下版本開始:

JDK1.0

另請(qǐng)參見:

Observable

?

public class Observableextends Object

此類表示模型視圖范例中的 observable 對(duì)象,或者說“數(shù)據(jù)”。可將其子類化,表示應(yīng)用程序想要觀察的對(duì)象。

一個(gè) observable 對(duì)象可以有一個(gè)或多個(gè)觀察者。觀察者可以是實(shí)現(xiàn)了 Observer 接口的任意對(duì)象。一個(gè) observable 實(shí)例改變后,調(diào)用 Observable 的 notifyObservers 方法的應(yīng)用程序會(huì)通過調(diào)用觀察者的 update 方法來通知觀察者該實(shí)例發(fā)生了改變。

?

未指定發(fā)送通知的順序。Observable 類中所提供的默認(rèn)實(shí)現(xiàn)將按照其注冊(cè)的重要性順序來通知 Observers,但是子類可能改變此順序,從而使用非固定順序在單獨(dú)的線程上發(fā)送通知,或者也可能保證其子類遵從其所選擇的順序。

?

注意,此通知機(jī)制與線程無關(guān),并且與 Object 類的 wait 和 notify 機(jī)制完全獨(dú)立。 新創(chuàng)建一個(gè) observable 對(duì)象時(shí),其觀察者集是空的。當(dāng)且僅當(dāng) equals 方法為兩個(gè)觀察者返回 true 時(shí),才認(rèn)為它們是相同的。

?

從以下版本開始:

JDK1.0

另請(qǐng)參見:?

notifyObservers(), notifyObservers(java.lang.Object), Observer, Observer.update(java.util.Observable, java.lang.Object)

?

舉個(gè)例子,如果你看過TVB的警匪片,你就知道臥底的工作方式。一般一個(gè)警察可能有幾個(gè)臥底,潛入敵人內(nèi)部,打探消息,臥底完全靠他的領(lǐng)導(dǎo)的指示干活,領(lǐng)導(dǎo)說幾點(diǎn)行動(dòng),他必須按照這個(gè)時(shí)間去執(zhí)行,如果行動(dòng)時(shí)間改變,他也要立馬改變自己配合行動(dòng)的時(shí)間。領(lǐng)導(dǎo)派兩個(gè)臥底去打入敵人內(nèi)部,那么領(lǐng)導(dǎo)相當(dāng)于抽象主題,而督察警官張三這個(gè)人派了兩個(gè)臥底李四和萬王五,張三就相當(dāng)于具體主題,臥底相當(dāng)于抽象觀察者,這兩名臥底是李四和王五就是具體觀察者,派的這個(gè)動(dòng)作相當(dāng)于觀察者在主題的登記。那么這個(gè)類圖如下:
利用javaAPI來實(shí)現(xiàn),代碼描述如下: ?
Java代碼?? 收藏代碼
  1. package ?observer;??
  2. ??
  3. import ?java.util.List;??
  4. import ?java.util.Observable;??
  5. import ?java.util.Observer;??
  6. /** ?
  7. ?*? ?
  8. ?*作者:alaric ?
  9. ?*時(shí)間:2013-8-13下午9:32:40 ?
  10. ?*描述:警察張三 ?
  11. ?*/ ??
  12. public ? class ?Police? extends ?Observable?{??
  13. ??
  14. ???? private ?String?time?;??
  15. ???? public ?Police(List<Observer>?list)?{??
  16. ???????? super ();??
  17. ???????? for ?(Observer?o:list)?{??
  18. ????????????addObserver(o);??
  19. ????????}??
  20. ????}??
  21. ???? public ? void ?change(String?time){??
  22. ???????? this .time?=?time;??
  23. ????????setChanged();??
  24. ????????notifyObservers( this .time);??
  25. ????}??
  26. }??
?
Java代碼?? 收藏代碼
  1. package ?observer;??
  2. ??
  3. import ?java.util.Observable;??
  4. import ?java.util.Observer;??
  5. /** ?
  6. ?*? ?
  7. ?*作者:alaric ?
  8. ?*時(shí)間:2013-8-13下午9:32:59 ?
  9. ?*描述:臥底A ?
  10. ?*/ ??
  11. public ? class ?UndercoverA? implements ?Observer?{??
  12. ??
  13. ???? private ?String?time;??
  14. ???? @Override ??
  15. ???? public ? void ?update(Observable?o,?Object?arg)?{??
  16. ????????time?=?(String)?arg;??
  17. ????????System.out.println( "臥底A接到消息,行動(dòng)時(shí)間為:" +time);??
  18. ????}??
  19. ??
  20. ??
  21. }??
?
Java代碼?? 收藏代碼
  1. package ?observer;??
  2. ??
  3. import ?java.util.Observable;??
  4. import ?java.util.Observer;??
  5. /** ?
  6. ?*? ?
  7. ?*作者:alaric ?
  8. ?*時(shí)間:2013-8-13下午9:33:14 ?
  9. ?*描述:臥底B ?
  10. ?*/ ??
  11. public ? class ?UndercoverB? implements ?Observer?{??
  12. ???? private ?String?time;??
  13. ???? @Override ??
  14. ???? public ? void ?update(Observable?o,?Object?arg)?{??
  15. ????????time?=?(String)?arg;??
  16. ????????System.out.println( "臥底B接到消息,行動(dòng)時(shí)間為:" +time);??
  17. ????}??
  18. ??
  19. ??
  20. ??
  21. }??
?
Java代碼?? 收藏代碼
  1. package ?observer;??
  2. ??
  3. import ?java.util.ArrayList;??
  4. import ?java.util.List;??
  5. import ?java.util.Observer;??
  6. /** ?
  7. ?*? ?
  8. ?*作者:alaric ?
  9. ?*時(shí)間:2013-8-13下午9:32:26 ?
  10. ?*描述:測(cè)試 ?
  11. ?*/ ??
  12. public ? class ?Client?{??
  13. ??
  14. ???? /** ?
  15. ?????*?@param?args ?
  16. ?????*/ ??
  17. ???? public ? static ? void ?main(String[]?args)?{??
  18. ????????UndercoverA?o1?=? new ?UndercoverA();??
  19. ????????UndercoverB?o2?=? new ?UndercoverB();??
  20. ????????List<Observer>?list?=? new ?ArrayList<>();??
  21. ????????list.add(o1);??
  22. ????????list.add(o2);??
  23. ????????Police?subject?=? new ?Police(list);??
  24. ????????subject.change( "02:25" );??
  25. ????????System.out.println( "===========由于消息敗露,行動(dòng)時(shí)間提前=========" );??
  26. ????????subject.change( "01:05" );??
  27. ??????????
  28. ????}??
  29. ??
  30. }??

?測(cè)試運(yùn)行結(jié)果:

臥底B接到消息,行動(dòng)時(shí)間為:02:25

臥底A接到消息,行動(dòng)時(shí)間為:02:25

===========由于消息敗露,行動(dòng)時(shí)間提前=========

臥底B接到消息,行動(dòng)時(shí)間為:01:05

臥底A接到消息,行動(dòng)時(shí)間為:01:05

觀察者模式的優(yōu)點(diǎn)是只要訂閱/登記了之后,當(dāng)被觀察者改變時(shí),觀察者能自動(dòng)更新。跟JMS一樣,消息發(fā)布者發(fā)出消息時(shí),只要注冊(cè)過的都會(huì)收到消息。

觀察者模式


更多文章、技術(shù)交流、商務(wù)合作、聯(lián)系博主

微信掃碼或搜索:z360901061

微信掃一掃加我為好友

QQ號(hào)聯(lián)系: 360901061

您的支持是博主寫作最大的動(dòng)力,如果您喜歡我的文章,感覺我的文章對(duì)您有幫助,請(qǐng)用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點(diǎn)擊下面給點(diǎn)支持吧,站長非常感激您!手機(jī)微信長按不能支付解決辦法:請(qǐng)將微信支付二維碼保存到相冊(cè),切換到微信,然后點(diǎn)擊微信右上角掃一掃功能,選擇支付二維碼完成支付。

【本文對(duì)您有幫助就好】

您的支持是博主寫作最大的動(dòng)力,如果您喜歡我的文章,感覺我的文章對(duì)您有幫助,請(qǐng)用微信掃描上面二維碼支持博主2元、5元、10元、自定義金額等您想捐的金額吧,站長會(huì)非常 感謝您的哦!!!

發(fā)表我的評(píng)論
最新評(píng)論 總共0條評(píng)論
主站蜘蛛池模板: 亚洲高清在线观看视频 | 国产一级免费在线观看 | 欧美日韩网站 | 人人狠狠综合久久亚洲88 | 一区二区三区欧美视频 | 99九九成人免费视频精品 | 月婷婷色狠狠 | 亚洲第一区视频在线观看 | 婷婷开心激情 | 4399一级成人毛片 | 香蕉黄视频 | 日韩精品一区二区三区中文字幕 | 老司机午夜精品视频你懂的 | 美女一级毛片免费不卡视频 | 伊人伊人伊人伊人 | 四虎网站1515hh四虎免费 | 91精品国产美女福到在线不卡 | 欧美成人免费tv在线播放 | 亚洲 国产 路线1路线2路线 | 夜夜撸天天干 | 国产综合久久久久久鬼色 | 99国产大尺度福利视频 | 免费视频一区二区性色 | 99久久国产综合精品女不卡 | 狠狠色噜噜狠狠狠狠五月婷 | 亚洲好色网 | 中文字幕在线免费观看 | 成人影院免费观看 | 最新69成人精品毛片 | 久久午夜国产片 | 91精品久久久久含羞草 | 成人另类 | 久久另类 | 国内免费一区二区三区视频 | 99精品视频在线成人精彩视频 | 日本亚洲欧美美色 | 精品久久久久久乐 | 日韩国产一区二区 | 色综合久久中文字幕综合网 | 日本免费高清一级毛片 | 香蕉视频网站 |