观察者模式:定义了对象之间的一对多的依赖,这样一来,当一个对象改变状态时,他的所有依赖者都会收到通知并自动更新;
系统描述:设计一个气象站,每当温度变化时,显示温度的布告板就会更新;
主题接口: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); } }观察者模式,就是在主题中设置一个观察点方法,每次运行该方法,就会通知所有的观察者,即调用观察者的通知方法,观察者在这个通知方法中进行其他处理。