什么是观察者设计模式
对象之间多对一依赖的一种设计方案,被依赖的对象叫Subject (所有的对象都要依赖他 一的一方),依赖的对象叫ObServer(多的一方)Subject通知Observe的变化。这样一来,当一个对象改变状态,依赖它的对象会收到通知并自动更新。好比于,发布者发布信息,订阅者获取信息,订阅了就能收到信息,没订阅就收不到信息。微信公众号就是一个典型的观察者设计模式。
观察者设计模式的原理
以气象站为例解释观察者设计模式
项目目录结构
package com.ghl.interfaces;
//主题接口
public interface Subject {
//添加观察者
void addObserver(Observer obj);
//移除观察者
void deleteObserver(Observer obj);
//当主题方法改变时,这个方法被调用,通知所有的观察者
void notifyObserver();
}
package com.ghl.interfaces;
//观察者接口
public interface Observer {
//当主题状态改变时,更新通知
public void update(float mTemperatrue,float mPressure,float mHumidity);
}
package com.ghl.interfaces;
//公告板类 第一个观察者
public class CurrentConditions implements Observer {
private float mTemperatrue;//气温
private float mPressure;//气压
private float mHumidity;//湿度
//当主题状态改变时,更新通知
@Override
public void update(float mTemperatrue, float mPressure, float mHumidity) {
this.mTemperatrue = mTemperatrue;
this.mPressure = mPressure;
this.mHumidity = mHumidity;
//调用更新的方法 进行显示
this.display();
}
public void display() {
System.out.println("****我是第一个观察者对象CurrentConditions*****");
System.out.println("今天的气温是:"+mTemperatrue);
System.out.println("今天的气压是:"+mPressure);
System.out.println("今天的湿度是:"+mHumidity);
}
}
package com.ghl.interfaces;
//公告板类 第二个观察者
public class ForcastConditions implements Observer {
private float mTemperatrue;//气温
private float mPressure;//气压
private float mHumidity;//湿度
//当主题状态改变时,更新通知
@Override
public void update(float mTemperatrue, float mPressure, float mHumidity) {
this.mTemperatrue = mTemperatrue;
this.mPressure = mPressure;
this.mHumidity = mHumidity;
//调用更新的方法 进行显示
this.display();
}
public void display() {
System.out.println("****我是第二个观察者对象ForcastConditions*****");
System.out.println("明天的气温是:"+mTemperatrue);
System.out.println("明天的气压是:"+mPressure);
System.out.println("明天的湿度是:"+mHumidity);
}
}
package com.ghl.interfaces;
import java.util.ArrayList;
import java.util.List;
/*
* 气象站实体类
*/
public class WeatherData implements Subject{
private float mTemperatrue;//气温
private float mPressure;//气压
private float mHumidity;//湿度
private List<Observer> mObserver=new ArrayList<>();//封装所有观察者对象
public float getmTemperatrue() {
return mTemperatrue;
}
public void setmTemperatrue(float mTemperatrue) {
this.mTemperatrue = mTemperatrue;
}
public float getmPressure() {
return mPressure;
}
public void setmPressure(float mPressure) {
this.mPressure = mPressure;
}
public float getmHumidity() {
return mHumidity;
}
public void setmHumidity(float mHumidity) {
this.mHumidity = mHumidity;
}
@Override
public void addObserver(Observer obj) {
//添加观察者 相当于关注公众号
mObserver.add(obj);
}
@Override
public void deleteObserver(Observer obj) {
// 移除观察者 不在关注公众号
mObserver.remove(obj);
}
//当气象站有新的数据 就会传入到这个方法中 进而通知给每个观察者对象
public void setData(float mTemperatrue, float mPressure, float mHumidity) {
this.mTemperatrue = mTemperatrue;
this.mPressure = mPressure;
this.mHumidity = mHumidity;
notifyObserver() ;//调用通知方法
}
@Override
public void notifyObserver() {
// 通知观察者 循环通知,因为会存在多个观察者对象 关注公众号的就会实时接收到最新的更新
for(int i=0;i<mObserver.size();i++) {
mObserver.get(i).update(getmTemperatrue(), getmPressure(), getmHumidity());
}
}
}
package com.ghl.interfaces;
//测试
public class WeatherTest {
public static void main(String[] args) {
CurrentConditions current=new CurrentConditions();//创建第一个观察者对象
ForcastConditions forcast=new ForcastConditions();//创建第二个观察者对象
WeatherData weather =new WeatherData();//创建主题接口对象(被观察者)
//把每个观察者对象注入进主题接口对象
weather.addObserver(current);//注入第一个观察者对象
weather.addObserver(forcast);//注入第二个观察者对象
//接下来模拟有新的数据了 看其他两个观察者对象能否接收到通知
weather.setData(100, 100, 2855);
}
}
运行结果
****我是第一个观察者对象CurrentConditions*****
今天的气温是:100.0
今天的气压是:100.0
今天的湿度是:2855.0
****我是第二个观察者对象ForcastConditions*****
明天的气温是:100.0
明天的气压是:100.0
明天的湿度是:2855.0
观察者设计模式的总结
第一步:创建一个被观察者对象的接口 Subject (接口内存在添加,移除,通知观察者的方法)
第二步:创建一个观察者对象的接口 Observer (接口内存在一个update方法 当主题状态发生改变时,更换通知)
第三步:创建观察者对象 实现第二步的接口
第四步:创建实习主题接口的类 重写三个方法
在这里我只是简单的阐述了观察者模式的原理,帮助大家弄懂这种优秀的设计模式。真正应用起来肯定会比这个例子复杂的多。