观察者模式Observer
初學(xué)java的觀察者模式,今天總結(jié)了下,希望指正。
觀察者模式定義了一種一對(duì)多的依賴(lài)關(guān)系,讓多個(gè)觀察者對(duì)象同時(shí)監(jiān)聽(tīng)某一個(gè)主題對(duì)象。
這個(gè)主題對(duì)象在狀態(tài)上發(fā)生變化時(shí),會(huì)通知所有觀察者對(duì)象,讓它們能夠自動(dòng)更新自己。
?所謂觀察者模式,舉個(gè)例子現(xiàn)在許多購(gòu)房者都密切觀察者房?jī)r(jià)的變化,當(dāng)房?jī)r(jià)變化時(shí),所有購(gòu)房者都能觀察到,以上的購(gòu)房者屬于觀察者,這便是觀察者模式。
???????Java中可以借助Observable類(lèi)和Observer接口輕松實(shí)現(xiàn)以上功能。當(dāng)然此種模式的實(shí)現(xiàn)也不僅僅局限于采用這兩個(gè)類(lèi)。
java.util.Observable中有兩個(gè)方法對(duì)Observer特別重要
1、setChanged()方法
/** 02. * If {@code hasChanged()} returns {@code true}, calls the {@code update()} 03. * method for every observer in the list of observers using null as the 04. * argument. Afterwards, calls {@code clearChanged()}. 05. * <p> 06. * Equivalent to calling {@code notifyObservers(null)}. 07. */ 08.public void notifyObservers() { 09. notifyObservers(null); 10.} 11. 12./** 13. * If {@code hasChanged()} returns {@code true}, calls the {@code update()} 14. * method for every Observer in the list of observers using the specified 15. * argument. Afterwards calls {@code clearChanged()}. 16. * 17. * @param data 18. * the argument passed to {@code update()}. 19. */ 20.@SuppressWarnings("unchecked") 21.public void notifyObservers(Object data) { 22. int size = 0; 23. Observer[] arrays = null; 24. synchronized (this) { 25. if (hasChanged()) { 26. clearChanged(); 27. size = observers.size(); 28. arrays = new Observer[size]; 29. observers.toArray(arrays); 30. } 31. } 32. if (arrays != null) { 33. for (Observer observer : arrays) { 34. observer.update(this, data); 35. } 36. } 37.} 以上兩個(gè)方法十分重要
setChanged()方法 ——
用來(lái)設(shè)置一個(gè)內(nèi)部標(biāo)志位注明數(shù)據(jù)發(fā)生了變化
notifyObservers()方法 / notifyObservers(Object data)方法 ——
通知所有的Observer數(shù)據(jù)發(fā)生了變化,這時(shí)所有的Observer會(huì)自動(dòng)調(diào)用復(fù)寫(xiě)好的update(Observable observable, Object data)方法來(lái)做一些處理(比如說(shuō)畫(huà)面數(shù)據(jù)的更新)。
我們可以看到通知Observer有兩個(gè)方法,一個(gè)無(wú)參,一個(gè)有參。那么這個(gè)參數(shù)有什么作用呢?
其中一個(gè)作用:現(xiàn)在我不想通知所有的Observer,而只想其中一個(gè)指定的Observer做一些處理,那么就可以傳一個(gè)參數(shù)作為ID,然后在所有的Observer中判斷,每個(gè)Observer判斷只有接收到底參數(shù)ID是屬于自己的才做一些處理。
當(dāng)然參數(shù)還有其他作用,我只是舉了個(gè)例子。
注意: 只有在setChanged()被調(diào)用后,notifyObservers()才會(huì)去調(diào)用update(),否則什么都不干。?????? 示例代碼如下:
import java.util.Observable; import java.util.Observer; class House extends Observable { private float price; public void setPrice(float price) { this.setChanged();// 設(shè)置變化點(diǎn) this.notifyObservers(price);// 通知所有觀察者價(jià)格改變 this.price = price; } public float getPrice() { return this.price; } public House(float price) { this.price = price; } public String toString() { return "房子價(jià)格為: " + this.price; } } class HousePriceObserver implements Observer { private String name; public HousePriceObserver(String name) { super(); this.name = name; } @Override public void update(Observable o, Object arg) {// 只要改變了 observable 對(duì)象就調(diào)用此方法 if (arg instanceof Float) { System.out.println(this.name + "觀察的價(jià)格更改為:" + ((Float) arg).floatValue()); } } } public class ObserTest { public static void main(String[] args) { House house = new House(1000000); HousePriceObserver hpo1 = new HousePriceObserver("購(gòu)房者A"); HousePriceObserver hpo2 = new HousePriceObserver("購(gòu)房者B"); HousePriceObserver hpo3 = new HousePriceObserver("購(gòu)房者C"); house.addObserver(hpo1);// 給房子注冊(cè)觀察者 house.addObserver(hpo2);// 給房子注冊(cè)觀察者 house.addObserver(hpo3);// 給房子注冊(cè)觀察者 System.out.println(house.toString());//輸出房子價(jià)格 // 修改房子價(jià)格,會(huì)觸發(fā)update(Observable o, Object arg)方法通知購(gòu)房者新的房?jī)r(jià)信息 house.setPrice(2222222);// System.out.println(house.toString());//再次輸出房子價(jià)格 } }
創(chuàng)作挑戰(zhàn)賽新人創(chuàng)作獎(jiǎng)勵(lì)來(lái)咯,堅(jiān)持創(chuàng)作打卡瓜分現(xiàn)金大獎(jiǎng)
總結(jié)
以上是生活随笔為你收集整理的观察者模式Observer的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: Java字节码增强探秘
- 下一篇: 面向对象六大原则——单一职责原则