1. 程式人生 > >觀察者模式(Observer)

觀察者模式(Observer)

urn 保持 com highlight notify () inter pattern import

觀察者模式主要用於 1:N的通知。當一個對象(目標對象Subject或Objservable)的狀態變化時,他需要及時告知一系列對象(觀察者對象Observer),令它們做出響應。

通知觀察者的方式:

  推:每次都會把通知以廣播的形式發送給所有觀察者,所有觀察者只能被動的接收。

  拉:觀察者只要知道有情況即可。至於什麽時候獲取內容,獲取什麽內容,都可以自主決定。

下面用代碼來說明:

  創建目標對象:

  

package com.note.pattern.observer;

import java.util.ArrayList;
import java.util.List;

/***
 *
 * 目標對象
 *
 */
public class Subject {

	protected List<Observer> list = new ArrayList<Observer>();

	public void registerObserver(Observer obs) {
		list.add(obs);
	}

	public void removeObserver(Observer obs) {
		list.add(obs);
	}

	// 通知所有的觀察者更新狀態
	public void notifyAllObservers() {
		for (Observer obs : list) {
			obs.update(this);
		}
	}

}

  

創建Observer接口:

package com.note.pattern.observer;

/**
 * 觀察者
 */
public interface Observer {
	
	void update(Subject subject);
	
}

  

創建具體的目標類:

package com.note.pattern.observer;

public class ConcreteSubject extends Subject {

	private int state;

	public int getState() {
		return state;
	}

	public void setState(int state) {
		this.state = state;
		// 主題對象(目標對象)值發生了變化,請通知所有的觀察者
		this.notifyAllObservers();
	}

}

  

定義Observer接口的實現類:

package com.note.pattern.observer;

public class ObserverA implements Observer{
	
	private int state; //myState需要跟目標對象的state值保持一致!

	@Override
	public void update(Subject subject) {
		state = ((ConcreteSubject)subject).getState();
	}

	public int getState() {
		return state;
	}

	public void setState(int state) {
		this.state = state;
	}

}

  

客戶端測試:

package com.note.pattern.observer;

public class Client {

	public static void main(String[] args) {
		// 目標對象
		ConcreteSubject subject = new ConcreteSubject();
		// 創建多個觀察者
		ObserverA obs1 = new ObserverA();
		ObserverA obs2 = new ObserverA();
		ObserverA obs3 = new ObserverA();

		// 將這三個觀察者添加到subject對象的觀察者隊伍中
		subject.registerObserver(obs1);
		subject.registerObserver(obs2);
		subject.registerObserver(obs3);

		// 改變subject的狀態
		subject.setState(3000);
		System.out.println("########################");
		// 我們看看,觀察者的狀態是不是也發生了變化
		System.out.println(obs1.getState());
		System.out.println(obs2.getState());
		System.out.println(obs3.getState());

		// 改變subject的狀態
		subject.setState(30);
		System.out.println("########################");
		// 我們看看,觀察者的狀態是不是也發生了變化
		System.out.println(obs1.getState());
		System.out.println(obs2.getState());
		System.out.println(obs3.getState());
	}

}

運行結果

########################
3000
3000
3000
########################
30
30
30

  

其實在JavaSE中已經提供了java.util.Observable和java.util.Observer來實現觀察者模式。

下面用java自帶的方式來實現:

創建具體目標對象,實現Observable接口即可:

package com.note.pattern.observer2;

import java.util.Observable;

/***
 * 目標對象
 *
 */
public class ConcreteSubject extends Observable{
	
	private int state;
	
	public void set(int s) {
		state = s;//目標對象的狀態發生了改變
		
		setChanged();//表示目標對象已經做了更改
		notifyObservers(state);//通知所有的觀察者
	}
	
	
}

  

創建觀察者,實現Observer接口:

package com.note.pattern.observer2;

import java.util.Observable;
import java.util.Observer;

public class ObserverA implements Observer {

	private int myState;

	@Override
	public void update(Observable o, Object arg) {
		myState = (int) arg;
	}
	
	public int getMyState() {
        return myState;
    }

}

  

客戶端測試:

package com.note.pattern.observer2;

public class Client {

	public static void main(String[] args) {
		// 創建目標對象Obserable
		ConcreteSubject subject = new ConcreteSubject();

		// 創建觀察者
		ObserverA obs1 = new ObserverA();
		ObserverA obs2 = new ObserverA();
		ObserverA obs3 = new ObserverA();

		// 將上面三個觀察者對象添加到目標對象subject的觀察者容器中
		subject.addObserver(obs1);
		subject.addObserver(obs2);
		subject.addObserver(obs3);

		// 改變subject對象的狀態
		subject.set(3000);
		System.out.println("===============狀態修改了!");
		// 觀察者的狀態發生了變化
		System.out.println(obs1.getMyState());
		System.out.println(obs2.getMyState());
		System.out.println(obs3.getMyState());

		subject.set(600);
		System.out.println("===============狀態修改了!");
		// 觀察者的狀態發生了變化
		System.out.println(obs1.getMyState());
		System.out.println(obs2.getMyState());
		System.out.println(obs3.getMyState());

	}

}

  

  

觀察者模式(Observer)