設計模式13--觀察者模式(Observer)

觀察者模式的本質:觸發聯動

當一個對象的狀態發生改變的時候,如何讓依賴它的所有對象得到通知,並進行相應的處理呢?

觀察者模式的定義:定義對象間的一種一對多的依賴關係。當一個對象的狀態發生改變時,所有依賴於它的對象都得到通知並被自動更新。

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

/**
 * 
 * 目標對象,它知道觀察它的觀察者,並提供註冊和刪除觀察者的接口
 *
 */
public class Subject {
	/**
	 * 用來保存註冊的觀察者對象
	 */
	private List<Observer> observers = new ArrayList<Observer>();
    /**
     * 註冊觀察者對象
     * @param observer觀察者對象
     */
	public void attach(Observer observer){
		observers.add(observer);
	}
	/**
     * 刪除觀察者對象
     * @param observer觀察者對象
     */
	public void detach(Observer observer){
		observers.remove(observer);
	}
	/**
	 * 通知所有註冊的觀察者對象
	 */
	protected void notifyObservers(){
		for(Observer observer:observers){
			observer.update(this);
		}
	}
}
/**
 * 
 * 具體的目標對象,負責把有關的狀態存入到相應的觀察者對象
 * 並在自己狀態發生變化時,通知各個觀察者
 *
 */
public class NewsPaper extends Subject{
	/**
	 * 報紙的具體內容
	 */
	private String content;

	public String getContent() {
		return content;
	}

	public void setContent(String content) {
		this.content = content;
		//狀態發生了改變,通知各個觀察者
		this.notifyObservers();
	}
	

}
/**
 * 
 * 觀察者接口,定義一個更新的接口給那些在目標發生改變的時候被通知的對象
 *
 */
public interface Observer {

	/**
	 * 更新的接口
	 * @param subject 傳入目標對象,方便獲取相應的目標對象的狀態
	 */
	public void update(Subject subject);
}
/**
 * 
 * 具體觀察者對象,實現更新的方法,使自身的狀態和目標的狀態保持一致
 *
 */
public class Reader implements Observer {
	
	private String name;
	
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	/**
     * 示意,觀察者的狀態
     */
	private String content;
	
	public String getContent() {
		return content;
	}
	public void setContent(String content) {
		this.content = content;
	}
	@Override
	public void update(Subject subject) {
		//具體的跟新實現
		//這裏可能需要更新觀察者的狀態,使其與目標的狀態保持一致
		content =((NewsPaper)subject).getContent();
		System.out.println(this.getName() + "收到報紙了,內容是" + this.getContent());

	}

}
public class Client {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		Reader observer1 = new Reader();
		observer1.setName("訂閱者1");
		Reader observer2 = new Reader();
		observer2.setName("訂閱者2");
		Reader observer3 = new Reader();
		observer3.setName("訂閱者3");
		
		NewsPaper subject = new NewsPaper();
		subject.attach(observer1);
		subject.attach(observer2);
		subject.attach(observer3);
		
		subject.setContent("SHIXIN747");

	}

}

Java中的觀察者模式:

import java.util.Observable;

/**
 * 
 * 具體的目標對象,負責把有關的狀態存入到相應的觀察者對象
 * 並在自己狀態發生變化時,通知各個觀察者
 *
 */
public class NewsPaper extends Observable{
	/**
	 * 報紙的具體內容
	 */
	private String content;

	public String getContent() {
		return content;
	}

	public void setContent(String content) {
		this.content = content;
		//狀態發生了改變,通知各個觀察者
		this.setChanged();
		//這裏是推的方式
		this.notifyObservers(this.content);
		//這裏是拉的方式
		this.notifyObservers();
	}
}
import java.util.Observable;
import java.util.Observer;

/**
 * 
 * 具體觀察者對象,實現更新的方法,使自身的狀態和目標的狀態保持一致
 *
 */
public class Reader implements Observer {
	
	private String name;
	
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	/**
     * 示意,觀察者的狀態
     */
	private String content;
	
	public String getContent() {
		return content;
	}
	public void setContent(String content) {
		this.content = content;
	}

	@Override
	public void update(Observable o, Object arg) {
		//這裏是獲取推的數據
		content = arg.toString();
		System.out.println(this.getName() + "收到報紙了,內容是" + this.getContent());
		
		//這裏是獲取拉的數據
		content =((NewsPaper)o).getContent();
		System.out.println(this.getName() + "收到報紙了,內容是" + this.getContent());
		
	}

}
public class Client {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		Reader observer1 = new Reader();
		observer1.setName("訂閱者1");
		Reader observer2 = new Reader();
		observer2.setName("訂閱者2");
		Reader observer3 = new Reader();
		observer3.setName("訂閱者3");
		
		NewsPaper newsPaper = new NewsPaper();
		newsPaper.addObserver(observer1);
		newsPaper.addObserver(observer2);
		newsPaper.addObserver(observer3);
		
		newsPaper.setContent("SHIXIN747");

	}

}


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