java设计模式--观察者模式(Observer)
java設計模式--觀察者模式(Observer)
觀察者模式的定義:
定義對象間的一種一對多的依賴關系。當一個對象的狀態發生改變時,所有依賴于它的對象
都得到通知并被自動更新。
認識觀察者模式:
1.目標和觀察者之間的關系:
按照模式的定義,目標和觀察者之間是典型的一對多的關系。
但是要注意,如果觀察者只有一個,也是可以的,這樣就變相的實現了目標和觀察者之間
一對一的關系。
?
2.觀察者模式中有四種對象:
Subject(目標對象),
Observer(定義觀察者接口),
ConcreteSubject(具體的目標實現對象),
ConcreteObserver(觀察者的具體實現對象)
一個目標可以有任意多個觀察者對象,一旦目標的狀態發生了改變,所有注冊的觀察者都會等到通知,
然后各個觀察者會對通知作出相應的響應,執行相應的業務功能處理,并使自己的狀態和目標的狀態保存一致。
Subject:目標對象接口,提供如下功能:
a.一個目標可以被多個觀察者觀察
b.目標提供對觀察者注冊和退訂的維護
c.當目標的狀態發生變化時,目標負責通知所有注冊的,有效的觀察者
Observer:觀察者的接口,提供目標通知時對應的更新方法,這個方法進行相應的業務處理,可以在這個方法
里面回調目標對象,以獲取目標對象的數據。
ConcreteSubject:具體的目標實現對象,用來維護目標狀態,當目標對象的狀態發生改變時,通知
所有注冊的、有效的觀察者,讓觀察者執行相應的處理。
ConcreteObserver:觀察者的具體實現對象,用來接收目標的通知,并進行相應的后續處理,比如更新
自身的狀態以保持和目標的相應狀態一致。
?
舉例:
?
/*** 功能:* 具體的目標對象,負責把有關狀態存入到相應的觀察者對象* 并在自己狀態發生改變時,通知各個觀察者* (報紙對象)* @author Administrator**/ public class NewPaper extends Subject {//報紙的具體內容private String content;/*** 功能:* 獲取報紙的具體內容* @return*/public String getContent(){return content;}/*** 功能:* 設置報紙的具體內容,相當于出版報紙* @param content*/public void setContent(String content){this.content = content;//通知所有注冊的讀者this.notifyAllObservers();} }?
/*** 功能:* 觀察者接口,定義一個更新的接口給那些在目標發生改變的時候被通知的對象* (報紙的讀者)* @author Administrator**/ public interface Observer {/*** 功能:* 更新的接口* @param subject 傳入目標對象,方便獲取相應的目標對象的狀態*/public void update(Subject subject); }?
/*** 功能:* 具體的觀察者對象,實現更新的方法,使自身的狀態和目標的狀態保存一致* (真正的讀者)* @author Administrator**/ public class Reader implements Observer {//讀者的姓名private String name;@Overridepublic void update(Subject subject){//這里采用拉的方式System.out.println(name + "收到報紙,內容為: "+ ((NewPaper)subject).getContent());}public String getName(){return name;}public void setName(String name){this.name = name;} }?
public class Client {public static void main(String[] args){//創建一個報紙,作為被觀察者NewPaper subject = new NewPaper();//創建閱讀者,也就是觀察者Reader reader1 = new Reader();reader1.setName("羅納爾多");Reader reader2 = new Reader();reader2.setName("貝克漢姆");//注冊觀察者 subject.attach(reader1);subject.attach(reader2);subject.setContent("世界杯要開始了哦.....");} }?
?
對上面的模式進行講解:
一、目標和觀察者之間的關系
按照模式的定義,目標和觀察者之間是典型的一對多的關系。
但是,觀察者也可以只有一個,這樣就實現了目標和觀察者之間一對一的關系。
同樣,一個觀察者可以觀察多個目標。
?
觀察者模式中的: 推模型和拉模型
推模型:
目標對象主動向觀察者推送目標的詳細信息,不管觀察者是否需要,推送的信息通常是
目標對象的全部或部分數據
拉模型:
目標對象在通知觀察者的時候,只傳遞少量信息。如果觀察者需要更具體的信息,
由觀察者主動到目標對象中獲取,相當于觀察者從目標對象中拉數據。
?
將上面的代碼通過推模型進行實現:
import java.util.ArrayList; import java.util.List;/*** 功能:* 目標對象,作為被觀察者,使用推模型* @author Administrator**/ public class Subject { //用來保存注冊的觀察者對象(報紙訂閱者)private List<Observer> readers = new ArrayList<Observer>();/*** 功能:* 注冊觀察者對象(報紙的讀者需要向報社訂閱,先要注冊)* @param observer 觀察者對象*/public void attach(Observer reader){readers.add(reader);}/*** 功能:* 刪除觀察者對象(報紙的讀者可以取消訂閱)* @param observer*/public void detach(Observer reader){readers.remove(reader);}/*** 功能:* 通知所有的觀察者* (當有報紙出版后,就要主動的送到讀者手中,相當于通知讀者)*/protected void notifyAllObservers(String content){for(Observer reader : readers){reader.update(content);}} }?
public class NewsPaper extends Subject {private String content;public String getContent(){return content;}public void setContent(String content){this.content = content;//通知所有注冊的觀察者(讀者)this.notifyAllObservers(content);} }?
/*** 功能:* 觀察者(報紙的讀者)* @author Administrator**/ public interface Observer {/*** 功能:* 被通知的方法,直接把報紙的內容推送過來* @param content*/public void update(String content); }?
public class Reader implements Observer {//讀者的姓名private String name;@Overridepublic void update(String content){//這里采用推的方式System.out.println(name + "收到報紙了,內容是:" + content);}public String getName(){return name;}public void setName(String name){this.name = name;} }?
public class Client {public static void main(String[] args){//創建一個報紙,作為被觀察者NewsPaper subject = new NewsPaper();//創建閱讀者,也就是觀察者Reader reader1 = new Reader();reader1.setName("羅納爾多");Reader reader2 = new Reader();reader2.setName("貝克漢姆");//注冊觀察者 subject.attach(reader1);subject.attach(reader2);subject.setContent("世界杯要開始了哦.....");} }?
兩種模型的比較:(1)推模型是假定目標對象知道觀察者需要的數據;而拉模型是目標對象不知道觀察者具體 需要什么數據,沒有辦法的情況下,把自身傳給觀察者,讓觀察者自己去按需取值。 (2)推模型可能會使得觀察者對象難以復用,因為觀察者定義的update方法是按需而定義的, 可能無法兼顧沒有考慮到的使用情況。這就意味著出現新情況的時候,就可能需要提供新的update方法, 或者干脆重新實現觀察者。java中的觀察者在java.util包里面有一個類Observable,實現了大部分目標的功能。 java.util包里面有一個類Observer,其中定義了update的方法,就是觀察者的接口?
?
import java.util.Observable;public class NewsPaper extends Observable {//報紙的具體內容private String content;/*** 功能:* 獲取報紙的具體內容* @return*/public String getContent(){return content;}/*** 功能:* 設置報紙的具體內容,相當于出版報紙* @param content*/public void setContent(String content){this.content = content;//通知觀察者this.setChanged();this.notifyObservers(this.content);//采用推的方法 } }?
import java.util.Observable; import java.util.Observer;/*** 功能:* 觀察者(讀者)* @author Administrator**/ public class Reader implements Observer {private String name;public String getName(){return name;}public void setName(String name){this.name = name;}@Overridepublic void update(Observable arg0, Object obj){System.out.println(name + "收到報紙了,內容為:"+obj);} }?
public class Client {public static void main(String[] args){//創建一個報紙,作為被觀察者NewsPaper subject = new NewsPaper();//創建閱讀者,也就是觀察者Reader reader1 = new Reader();reader1.setName("羅納爾多");Reader reader2 = new Reader();reader2.setName("貝克漢姆");//注冊閱讀者 subject.addObserver(reader1);subject.addObserver(reader2);//出版報紙subject.setContent("世界杯要開始了咯");} }?
觀察者模式的本質:觸發聯動
當修改目標對象的狀態的時候,就會觸發相應的通知,然后會循環的調用所有注冊的觀察者對象
的相應方法,其實就相當于聯動調用這些觀察者的方法。
這個聯動還是動態的,可以通過注冊和取消注冊來控制觀察者,因而可以可以在程序運行期間,
通過動態的控制觀察者,來變相地實現添加和刪除某些功能處理,這些功能就是觀察者在update的
時候執行的功能。
轉載于:https://www.cnblogs.com/baiduligang/p/4247420.html
總結
以上是生活随笔為你收集整理的java设计模式--观察者模式(Observer)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: MD3200扩展柜MD1200,玩起
- 下一篇: iOS UITableView