設計模式之觀察者模式

1、概念(百科)

觀察者模式(有時又被稱爲發佈(publish )-訂閱(Subscribe)模式、模型-視圖(View)模式、源-收聽者(Listener)模式或從屬者模式)是軟件設計模式的一種。在此種模式中,一個目標物件管理所有相依於它的觀察者物件,並且在它本身的狀態改變時主動發出通知。這通常透過呼叫各觀察者所提供的方法來實現。此種模式通常被用來實現事件處理系統。

2、實現方式

觀察者模式包含有兩個角色:觀察者(Observer)和目標者[/被觀察者](Subject),二者之間存在“觀察”的邏輯關聯,當目標狀態發生變化時,所有依賴於目標的對象都會得到通知並自動刷新。

3、大致過程

wKioL1doJw6hVvFnAAAymxnJzuI492.jpg-wh_50

涉及角色:

3.1 目標者(Subject)抽象類,包括對觀察者的註冊,撤銷和發送通知

3.2 具體目標(ConcreteSubject)記錄目標者的相關狀態。在狀態更新時,通知所有註冊在本目標的觀察者

3.3 觀察者(Observer)爲所有觀察者定義一個接口,得到狀態更新時更新自己

3.4 具體觀察者(ConcreteObserver)實現抽象觀察者所要求的更新接口,以便使本身的狀態和主題狀態協調


4、相關代碼

4.1 目標者代碼

import java.util.ArrayList;

import java.util.List;


public abstract class Subject {

private List<Observer> observers = new ArrayList<Observer>();


public void attach(Observer observer) {

this.observers.add(observer);

}


public void dettach(Observer observer) {

this.observers.remove(observer);

}


protected void notifyObservers() {

for(Observer observer:observers){

observer.update(this);

}

}


}


public class ConstreteSubject extends Subject {

//目標對象的狀態

private String subjectState;

/**

* @return the subjectState

*/

public String getSubjectState() {

return subjectState;

}


/**

* @param subjectState the subjectState to set

*/

public void setSubjectState(String subjectState) {

this.subjectState = subjectState;

this.notifyObservers();

}


}


4.2 觀察者代碼

public interface Observer {

/**

* 更新的接口

* @param subject傳入目標對象,方便獲取響應的目標對象的狀態

*/

public void update(Subject subject);


}



public class ConstreteObserver implements Observer {

/**

     * 獲取目標類的狀態同步到觀察者的狀態

     */

@Override

public void update(Subject subject) {

   System.out.println("觀察者收到目標者的更新狀態是:" + ((ConstreteSubject)subject).getSubjectState());

}


}

以上描述了觀察者模式的具體實現,目前JDK已經提供該模式的實現標準,在使用過程中,不需要再像上面一樣完成自己實現整個過程,只需要實現java.util.Observable接口即可。

5、JDK標準實現

模擬一個場景,瑞士公投全球最高底薪標準,假如公投通過,作爲老闆和員工的反應肯定是不一樣的,此處公投內容爲目標者或者叫被觀察者,老闆和僱員作爲觀察者。看具體代碼

5.1 目標

import java.util.Observable;


//公投目標的具體實現類

public class ConcreteSubject extends Observable {

    //公投的具體內容

private String content;


/**

* @return the content

*/

public String getContent() {

return content;

}


/**

* @param content the content to set

*/

public void setContent(String content) {

this.content = content;

//通知所有的觀測者

//注意在通知之前,在用JAVA的Observer模式,下面這句不可少

this.setChanged();

//主動通知,推實現

this.notifyObservers(this.content);

//拉方式,不帶參數

//this.notifyObservers();

}

}


5.2 觀察者

import java.util.Observable;

import java.util.Observer;


public class ConcreteObserver implements Observer {

//觀察者名稱

private String ObserverName;


@Override

public void update(Observable arg0, Object arg1) {

//推

if("老闆".equals(this.ObserverName)){

System.out.println(this.ObserverName + "接到最低時薪公投結果:" + arg1 + ",大罵:F**k成本上升了。。。");

}else if("僱員".equals(this.ObserverName)){

System.out.println(this.ObserverName + "接到最低時薪公投結果:" + arg1 + ",開心:^_^ 收入增加了。。。");

}

}


/**

* @return the observerName

*/

public String getObserverName() {

return ObserverName;

}


/**

* @param observerName the observerName to set

*/

public void setObserverName(String observerName) {

ObserverName = observerName;

}


}


5.3 測試類


public class Client {


public static void main(String[] args) {

//被觀察者

ConcreteSubject subject = new ConcreteSubject();

//觀察者

ConcreteObserver boss = new ConcreteObserver();

boss.setObserverName("老闆");

//觀察者

ConcreteObserver emp = new ConcreteObserver();

emp.setObserverName("僱員");

//註冊觀察者

subject.addObserver(boss);

subject.addObserver(emp);

//公投結果

subject.setContent("通過");


}


}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章