定义:观察者模式(有时又被称为发布(publish )-订阅(Subscribe)模式、模型-视图(View)模式、源-收听者(Listener)模式或从属者模式)是软件设计模式的一种。在此种模式中,一个目标物件管理所有相依于它的观察者物件,并且在它本身的状态改变时主动发出通知。这通常透过呼叫各观察者所提供的方法来实现。此种模式通常被用来实现事件处理系统。
用自己的话说:思想是往观察者里面注入主体,但是是主体里面有list去存储观察者,也是由主体去调动观察者的,但是从客户面前看,就是观察者去观察主体,因为是把主体传给他的。
代码:
首先,定义一个观察者的接口,主要用于修改数据:
public interface Observer {
//当主题改变时,该接口会被调用
public void update(float temp,float humidity,float pressure);
}
定义一个通用接口,用于展示数据
public interface DisplayElement {
public void display();//所有观察者调用该方法显示数据
}
定义一个主体接口:
/**
* 主题类,该主题一经改变,将会通知内在的观察者类
* @author jiangjintai
*
*/
public interface Subject {
public void registerObserver(Observer o);//注册观察者
public void removeObserver(Observer o);//移除观察者
public void notifyObserver();//通知所有的观察者
}
定义一个观察者实体:
public class CurrentConditionsDisplay implements Observer,DisplayElement {
private float temp;
private float humidity;
private float pressure;
/**
*
*/
public CurrentConditionsDisplay(Subject subject) {
// TODO 自动生成的构造函数存根
//调用构造函数时,让主体去调用注方法,注册自己
subject.registerObserver(this);
}
/* (非 Javadoc)
* @see com.jjt.observer.Observer#update(float, float, float)
*/
@Override
public void update(float temp, float humidity, float pressure) {
// TODO 自动生成的方法存根
this.temp=temp;
this.humidity=humidity;
this.pressure=pressure;
this.display();
}
/* (非 Javadoc)
* @see com.jjt.observer.DisplayElement#display()
*/
@Override
public void display() {
// TODO 自动生成的方法存根
System.out.println(this.humidity+""+this.pressure+this.temp);
}
}
定义一个主体实体:
public class WeatherData implements Subject {
private ArrayList<Observer> observes;
private float temperature;
private float humidity;
private float pressure;
public WeatherData(){
this.observes= new ArrayList<Observer>();
}
/* (非 Javadoc)
* @see com.jjt.observer.Subject#registerObserver(com.jjt.observer.Observer)
*/
@Override
public void registerObserver(Observer o) {
// TODO 自动生成的方法存根
this.observes.add(o);
}
/* (非 Javadoc)
* @see com.jjt.observer.Subject#removeObserver(com.jjt.observer.Observer)
*/
@Override
public void removeObserver(Observer o) {
// TODO 自动生成的方法存根
this.observes.remove(0);
}
/* (非 Javadoc)
* @see com.jjt.observer.Subject#notifyObserver()
*/
@Override
public void notifyObserver() {
// TODO 自动生成的方法存根
for(Observer o :observes){
o.update(temperature, humidity, pressure);
}
}
public void measurementsChanged(){
notifyObserver();
}
public void setMeasurements(float temperature,float humidity,float pressure){
this.temperature=temperature;
this.humidity=humidity;
this.pressure=pressure;
this.measurementsChanged();
}
}
测试:
public static void main(String[] args){
WeatherData weatherData = new WeatherData();//这是一个主体
Observer o = new CurrentConditionsDisplay(weatherData);//这是一个观察者
weatherData.setMeasurements(1, 2, 3);//主体改变内容,观察者里面的动作杯调用
//思想是往观察者里面注入主体,但是是主体里面有list去存储观察者,也是由主体去调动观察者的,
//但是从客户面前看,就是观察者去观察主体,因为是把主体传给他的。
}
结果:
2.03.01.0
java api提供了一套api可用于观察者模式
java.util.Observable:一个观察者的实现类,继承它便可以实现一个主体类,通过本类的
this.notifyObservers("123");
调用所有的观察者类,可以传入任意参数,该参数可以被传到所有的观察者中。
java.util.Observer:一个观察者接口。实现他可以实现可以观察者。
1.通过构造函数,可以传入主体类,对观察者进行注册
2.实现
public void update(Observable o, Object arg) {}
//o表示主体,arg表示刚刚notifyObservers里面传入的参数
方法,可以完成观察者本身与主体的交互。
代码:
定义一个主题类:
public class WeatherData extends Observable {
private float temp;
private float pressure;
private float humidity;
public void setMeasurememts(float temp,float pressure,float humidity){
this.temp= temp;
this.pressure = pressure;
this.humidity = humidity;
this.setChanged();
this.notifyObservers("123");
}
public float getTemp() {
return temp;
}
public float getPressure() {
return pressure;
}
public float getHumidity() {
return humidity;
}
}
定义一个观察者类:
public class CurrentConditionsDisplay implements Observer,DisplayElement {
private float temp;
private float pressure;
private float humidity;
/**
*
*/
public CurrentConditionsDisplay(Observable weatherData) {
// TODO 自动生成的构造函数存根
weatherData.addObserver(this);
}
/* (非 Javadoc)
* @see java.util.Observer#update(java.util.Observable, java.lang.Object)
*/
@Override
public void update(Observable o, Object arg) {
// TODO 自动生成的方法存根
if(o instanceof WeatherData){
WeatherData w = (WeatherData)o;
this.temp=w.getTemp();
this.humidity=w.getHumidity();
this.pressure=w.getPressure();
this.display();
}
System.out.println("object:"+(String)arg.toString());
}
/* (非 Javadoc)
* @see com.jjt.observer.DisplayElement#display()
*/
@Override
public void display() {
// TODO 自动生成的方法存根
System.out.println(""+this.temp+this.pressure+this.humidity);
}
}