通俗的说:我们向报社订阅报纸,这个就是观察者模式的实例,我们是观察者(Observer),报社就是主题(Subject)。
观察者模式定义了对象之间的一对多依赖,这样一来,当一个对象改变状态时,它的所有依赖者都会收到通知并自动更新。
现在我们设计一个气象监测站系统,此系统中的三个部分分别是气象站(获取实际气象数据)、布告板(显示当前的天气状况)
、WeatherData(跟踪来自气象站的数据,并更新布告板),布告板可以提供扩展。
系统设计类图如下:
/**
* 主题
* @author wengn
*
*/
public interface Subject {
public void registerObserver(Observer o);
public void removeObserver(Observer o);
public void notifyObserver();
}
/**
* 观察者
* @author wengn
*
*/
public interface Observer {
public void update(float temp,float humidity,float pressure);
}
/**
* 布告板接口
* @author wengn
*
*/
public interface DisplayElement {
public void display();
}
/**
* 主题实现类
* @author Administrator
*
*/
public class WeatherData implements Subject {
private ArrayList observers;
private float temperature;
private float humidity;
private float pressure;
public WeatherData(){
observers = new ArrayList();
}
public void notifyObserver() {
for(int i=0;i<observers.size();i++){
Observer o = (Observer)observers.get(i);
o.update(temperature, humidity, pressure);
}
}
public void registerObserver(Observer o) {
observers.add(o);
}
public void removeObserver(Observer o) {
int i = observers.indexOf(o);
if(i>=0){
observers.remove(i);
}
}
public void measurementsChanged(){
this.notifyObserver();
}
public void setMeasurements(float temperature,float humidity,float pressure){
this.temperature = temperature;
this.humidity = humidity;
this.pressure = pressure;
measurementsChanged();
}
}
/**
* 布告板实现类
* @author wengn
*
*/
public class CurrentConditionsDisplay implements Observer, DisplayElement {
private float temperature;
private float humidity;
private Subject weatherData;
public CurrentConditionsDisplay(Subject s){
this.weatherData = s;
weatherData.registerObserver(this);
}
public void update(float temp, float humidity, float pressure) {
this.temperature = temp;
this.humidity = humidity;
display();
}
public void display() {
System.out.println("show:"+temperature+"||"+humidity);
}
}
/**
* 测试类
* @author wengn
*
*/
public class Test {
public static void main(String[] args) {
WeatherData wd = new WeatherData();
CurrentConditionsDisplay ccd = new CurrentConditionsDisplay(wd);
wd.setMeasurements(0, 0, 0);
wd.setMeasurements(1, 1, 1);
wd.setMeasurements(2, 2, 2);
}
}
附上java awt中观察者模式的模拟代码:
package com.hanbing.awt;
import java.util.ArrayList;
import java.util.List;
public class MyAwt {
public static void main(String[] args) {
Button bt = new Button();
MyActionLisenter lisenter = new MyActionLisenter();
MyActionLisenter2 lisenter2 = new MyActionLisenter2();
bt.addActionLisenter(lisenter);
bt.addActionLisenter(lisenter2);
bt.buttonPressed();
}
}
class Button {
private List<ActionLisenter> list = new ArrayList<ActionLisenter>();
public void buttonPressed() {
ActionEvent e = new ActionEvent(System.currentTimeMillis(), this);
for (ActionLisenter lisenter:list) {
lisenter.actionPerformed(e);
}
}
public void addActionLisenter(ActionLisenter lisenter) {
list.add(lisenter);
}
}
interface ActionLisenter {
public void actionPerformed(ActionEvent e);
}
class MyActionLisenter implements ActionLisenter {
public void actionPerformed(ActionEvent e) {
System.out.println("oh my god!!!");
}
}
class MyActionLisenter2 implements ActionLisenter {
public void actionPerformed(ActionEvent e) {
System.out.println("oh my god2!!!");
}
}
class ActionEvent {
private long when;
private Object source;
public ActionEvent(long when, Object source) {
super();
this.when = when;
this.source = source;
}
public long getWhen() {
return when;
}
public Object getSource(){
return source;
}
}