观察者模式:定义了对象之间的一对多的依赖,这样一来,当一个对象改变状态时,他的所有依赖者都会收到通知并自动更新;
系统描述:设计一个气象站,每当温度变化时,显示温度的布告板就会更新;
主题接口:Subject.java
package cn.weather.demo;
/**
* 主题接口
* @author wy
*
*/
public interface Subject {
//注册观察者
public void registerObserver(Observer o);
//移除观察者
public void removeObserver(Observer o);
//通知观察者
public void notifyObserver();
}
观察者接口:
package cn.weather.demo;
/**
* 观察者接口
* @author wy
*
*/
public interface Observer {
public void update (int temp,int humidity);
}
布告板接口
package cn.weather.demo;
public interface DisplayData {
public void display();
}
一个具体的主题,这是被观察的对象,在主题中有一个观察者的集合,
package cn.weather.demo;
import java.util.ArrayList;
public class WeatherData implements Subject {
private ArrayList<Observer> observers;
private int temp;
private int humidity;
public WeatherData() {
observers = new ArrayList<Observer>();
}
@Override
public void registerObserver(Observer o) {
// TODO Auto-generated method stub
observers.add(o);
}
@Override
public void removeObserver(Observer o) {
// TODO Auto-generated method stub
observers.remove(o);
}
@Override
public void notifyObserver() {
// TODO Auto-generated method stub
for (Observer observer : observers) {
observer.update(temp, humidity);
}
}
public void measurementChanged() {
notifyObserver();
}
public void setMeasurements(int temp, int humidity) {
this.temp = temp;
this.humidity = humidity;
measurementChanged();
}
}
创建一个布告板,也就是观察者,其中包含了主题通知该观察者时所需要做的动作
package cn.weather.demo;
import java.awt.image.ImageConsumer;
public class FirstDisplayer implements Observer, DisplayData {
private int temp;
private int humidity;
private Subject weather;
public FirstDisplayer(Subject weather) {
this.weather = weather;
weather.registerObserver(this);
}
@Override
public void update(int temp, int humidity) {
this.temp = temp;
this.humidity = humidity;
display();
}
@Override
public void display() {
System.out.println("first displayer:");
System.out.println("temp:" + temp + "; humidity: " + humidity + "; ");
System.out.println();
}
}
在创建2个观察者
package cn.weather.demo;
public class SecondDisplayer implements Observer, DisplayData {
private int temp, humidity;
private Subject subject;
public SecondDisplayer(Subject subject) {
this.subject = subject;
subject.registerObserver(this);
}
@Override
public void display() {
// TODO Auto-generated method stub
System.out.println("second diplayer: ");
System.out.println("temp:" + this.temp + "; humidity:" + this.humidity);
System.out.println();
}
@Override
public void update(int temp, int humidity) {
// TODO Auto-generated method stub
this.temp = temp;
this.humidity = humidity;
display();
}
}
package cn.weather.demo;
public class ThirdDisplayer implements Observer {
private int min;
private int sec;
private Subject subject;
public ThirdDisplayer(Subject subject) {
this.subject = subject;
subject.registerObserver(this);
}
@Override
public void update(int min, int sec) {
this.min = min;
this.sec = sec;
show();
}
public void show() {
System.out.println("third displayer:");
System.out.println("min:" + min + "; sec:" + sec);
System.out.println();
}
}
测试:
package cn.weather.demo;
import java.util.Date;
public class Test {
public static void main(String[] args) {
WeatherData weatherData = new WeatherData();
FirstDisplayer firstDisplayer = new FirstDisplayer(weatherData);
weatherData.setMeasurements(10, 20);
SecondDisplayer secondDisplayer = new SecondDisplayer(weatherData);
weatherData.setMeasurements(500, 200);
weatherData.setMeasurements(300, 0);
}
}
观察者模式,就是在主题中设置一个观察点方法,每次运行该方法,就会通知所有的观察者,即调用观察者的通知方法,观察者在这个通知方法中进行其他处理。