觀察者模式定義了對象間的一對多關係,讓一個或多個觀察者對象觀察一個主題對象。當主題對象發生改變時,系統可以通知所有依賴於此對象的觀察者對象,從而使觀察者對象可以自動更新。
下面給出一個簡單的示範程序:
/**
*
*/
package com.zhjjie.modeltest.ObserverModel;
import java.util.Observable;
/**
* @author ; Administrator
* @Description : Observable 是所有被觀察者基類
* Product是一個具體的被觀察者類
* @CreateDate ; Aug 20, 2012 8:18:37 PM
* @lastModified ; Aug 20, 2012 8:18:37 PM
* @version ; 1.0
*/
public class Product extends Observable {
private String name ;
private Double price;
/**
*
*/
public Product() {
super();
}
/**
* @param name
* @param price
*/
public Product(String name, Double price) {
super();
this.name = name;
this.price = price;
}
/**
* @return the name
*/
public String getName() {
return name;
}
/**
* 當程序調用name的set方法來修改product的name屬性時,程序自然觸發該對象上註冊的所有觀察者
*/
public void setName(String name) {
this.name = name;
setChanged();
notifyObservers(name);
}
/**
* @return the price
*/
public Double getPrice() {
return price;
}
/**
* @當程序調用price的set方法來修改product的price屬性時,程序自然觸發該對象上註冊的所有觀察者
*/
public void setPrice(Double price) {
this.price = price;
setChanged();
notifyObservers(price);
}
}
/**
*
*/
package com.zhjjie.modeltest.ObserverModel;
import java.util.Observable;
import java.util.Observer;
/**
* @author ; Administrator
* @Description : Observer 是所有的觀察者接口,此接口中只有一個update方法
* NameObserver 是程序中的一個實現類
* @CreateDate ; Aug 20, 2012 8:32:19 PM
* @lastModified ; Aug 20, 2012 8:32:19 PM
* @version ; 1.0
*/
public class NameObserver implements Observer {
public void update(Observable o, Object arg) {
if(arg instanceof String){
String name = (String)arg;
System.out.println("名稱觀察者:"+this+" 物品名稱已經改變爲:"+name);
}
}
}
/**
*
*/
package com.zhjjie.modeltest.ObserverModel;
import java.util.Observable;
import java.util.Observer;
/**
* @author ; Administrator
* @Description : Observer 是所有的觀察者接口,此接口中只有一個update方法
* PriceObserver 是程序中的一個實現類
* @CreateDate ; Aug 20, 2012 8:37:32 PM
* @lastModified ; Aug 20, 2012 8:37:32 PM
* @version ; 1.0
*/
public class PriceObserver implements Observer {
public void update(Observable o, Object arg) {
if(arg instanceof Double){
Double price = (Double)arg;
System.out.println("價格觀察者:"+this+" 物品價格已經改變爲:"+price);
}
}
}
/**
*
*/
package com.zhjjie.modeltest.ObserverModel;
/**
* @author ; Administrator
* @Description : TODO
* @CreateDate ; Aug 20, 2012 8:38:50 PM
* @lastModified ; Aug 20, 2012 8:38:50 PM
* @version ; 1.0
*/
public class Main {
public static void main (String[] args){
Product p = new Product("電腦",3020.00);//創建一個被觀察者
//創建兩個觀察者
NameObserver n = new NameObserver();
PriceObserver po = new PriceObserver();
//向被觀察者對象上註冊兩個觀察者對象
p.addObserver(n);
p.addObserver(po);
//程序調用set方法改變product的name和price屬性值
p.setName("鍵盤");
p.setPrice(33.00);
}
}
運行上面的程序,我們將看到當Product的屬性值發生改變時,註冊在該product上的NameObserver和PriceObserver將被觸發。
總結觀察者模式,可知它一般包含四個角色:
1、被觀察者的抽象基類,該基類中通常會有多個觀察者的引用(java提供了java.util.Observerable 基類來代表被觀察者的抽象基類)
2、觀察者接口,該接口是所有觀察者應該要實現的接口,該接口中一般只含有一個update方法(java提供了java.util.Observer 接口代表觀察者的接口)
3、被觀察實現類
4、觀察者實現類
java事件機制的底層就是通過觀察者設計模式來實現的。其實,我們完全可以把觀察者接口理解爲事件監聽接口,而被觀察者對象也可當做事件源來處理。
另外,Spring中ApplicationContext的事件機制也是通過觀察者設計模式來實現的:
ApplicationEvent:容器事件 (被觀察者基類),必須由ApplicationContext發佈
ApplicationListener:監聽器(觀察者接口),可由容器中的任何監聽器Bean擔任。