案例
引入一个很常见的案例。现在有一家气象站负责发布气象消息(WeatherData),作为不同的客户,会有不同的对于气象消息的需求,我们也就需要设计一个或者多个面向用户的消息面板获取气象总站的消息,并更新给用户满意的定制数据,用来获取报酬。
Internet气象站项目:
- 提供温度、气压和湿度的接口
- 测量数据更新时需时时通知给第三方
- 需要设计开放型API,便于其他第三方公司也能接入气象站获取数据
用OOP思想,代码如下:
1.服务提供方
@Data
public class WeatherData {
private float mTemperature;
private float mPressure;
private float mHumidity;
private CurrentConditions currentConditions;
public WeatherData(CurrentConditions currentConditions) {
this.currentConditions = currentConditions;
}
public void setData(float mTemperature, float mPressure, float mHumidity){
this.mTemperature = mTemperature;
this.mPressure = mPressure;
this.mHumidity = mHumidity;
setChange();
}
private void setChange() {
currentConditions.setData(mTemperature, mPressure, mHumidity);
}
}
2.观察者
@Data
public class CurrentConditions {
private float mTemperature;
private float mPressure;
private float mHumidity;
public void setData(float mTemperature,float mPressure,float mHumidity){
this.mTemperature = mTemperature;
this.mPressure = mPressure;
this.mHumidity = mHumidity;
display();
}
public void display(){
System.out.println("mTemperature ="+mTemperature);
System.out.println("mPressure ="+mPressure);
System.out.println("mHumidity ="+mHumidity);
}
}
3.客户端测试
public class Tests {
public static void main(String[] args) {
CurrentConditions cns = new CurrentConditions();
WeatherData wd = new WeatherData(cns);
wd.setData(12, 55, 88);
}
}
有些问题
1)其他第三方公司接入气象站获取数据的问题
2)无法在运行时动态的添加第三方
观察者模式: 对象之间多对一依赖的一种设计方案,被依赖的对象为Subject,依赖的对象为Observer,Subject通知Observer变化
代码实现如下:
//服务提供方接口
public interface Subject {
void register(Observer e);
void remove(Observer e);
}
//观察者接口基类
public interface Observer {
void updateDatas(float mTemperature, float mPressure, float mHumidity);
}
服务端实现如下:
@Data
public class WeatherDataSt implements Subject{
private float mTemperature;
private float mPressure;
private float mHumidity;
private List<Observer> lists;
public WeatherDataSt() {
this.lists = new ArrayList<Observer>();
}
public void setData(float mTemperature, float mPressure, float mHumidity){
this.mTemperature = mTemperature;
this.mPressure = mPressure;
this.mHumidity = mHumidity;
notifyAllObserver();
}
private void notifyAllObserver() {
for(Observer item:lists){
item.updateDatas(mTemperature, mPressure, mHumidity);
}
}
@Override
public void register(Observer e) {
lists.add(e);
}
@Override
public void remove(Observer e) {
if(lists.contains(e)){
lists.remove(e);
}
}
}
观察者代码实现
@Data
public class CurrentConditions implements Observer{
private float mTemperature;
private float mPressure;
private float mHumidity;
public void display(){
System.out.println("CurrentConditions mTemperature ="+mTemperature);
System.out.println("CurrentConditions mPressure ="+mPressure);
System.out.println("CurrentConditions mHumidity ="+mHumidity);
}
@Override
public void updateDatas(float mTemperature, float mPressure, float mHumidity) {
this.mTemperature = mTemperature;
this.mPressure = mPressure;
this.mHumidity = mHumidity;
display();
}
}
@Data
public class FutureConditions implements Observer{
private float mTemperature;
private float mPressure;
private float mHumidity;
public void display(){
System.out.println("FutureConditions mTemperature ="+mTemperature);
System.out.println("FutureConditions mPressure ="+mPressure);
System.out.println("FutureConditions mHumidity ="+mHumidity);
}
@Override
public void updateDatas(float mTemperature, float mPressure, float mHumidity) {
this.mTemperature = mTemperature;
this.mPressure = mPressure;
this.mHumidity = mHumidity;
display();
}
}
测试代码:
public class Test {
public static void main(String[] args) {
Observer current = new CurrentConditions();
Observer forcast = new FutureConditions();
WeatherDataSt sj = new WeatherDataSt();
sj.register(current);
sj.register(forcast);
sj.setData(22, 55, 88);
System.out.println("----");
sj.remove(current);
sj.setData(229, 559, 889);
}
}
Java内置观察者
Java内置的观察者
Observable 是类,需要被继承
Observer
代码实现
1.服务端代码
public class WeatherDataSt extends Observable{
private float mTemperature;
private float mPressure;
private float mHumidity;
public void setData(float mTemperature,float mPressure,float mHumidity){
this.mTemperature = mTemperature;
this.mPressure = mPressure;
this.mHumidity = mHumidity;
notifyClient();
}
private void notifyClient() {
this.setChanged();
this.notifyObservers(new DataModule(mTemperature, mPressure, mHumidity));
}
}
2.客户端代码
@Data
public class CurrentConditions implements Observer{
private float mTemperature;
private float mPressure;
private float mHumidity;
public void display(){
System.out.println("CurrentConditions mTemperature ="+mTemperature);
System.out.println("CurrentConditions mPressure ="+mPressure);
System.out.println("CurrentConditions mHumidity ="+mHumidity);
}
@Override
public void update(Observable o, Object arg) {
DataModule dm = (DataModule) arg;
this.mTemperature = dm.mTemperature;
this.mPressure = dm.mPressure;
this.mHumidity = dm.mHumidity;
display();
}
}
@Data
public class FutureConditions implements Observer{
private float mTemperature;
private float mPressure;
private float mHumidity;
public void display(){
System.out.println("FutureConditions mTemperature ="+mTemperature);
System.out.println("FutureConditions mPressure ="+mPressure);
System.out.println("FutureConditions mHumidity ="+mHumidity);
}
@Override
public void update(Observable o, Object arg) {
DataModule dm = (DataModule) arg;
this.mTemperature = dm.mTemperature;
this.mPressure = dm.mPressure;
this.mHumidity = dm.mHumidity;
display();
}
}
3.测试以及其他
@Data
public class DataModule {
public float mTemperature;
public float mPressure;
public float mHumidity;
public DataModule(float mTemperature, float mPressure, float mHumidity) {
super();
this.mTemperature = mTemperature;
this.mPressure = mPressure;
this.mHumidity = mHumidity;
}
}
public class Test {
public static void main(String[] args) {
Observer current = new CurrentConditions();
Observer forcast = new FutureConditions();
WeatherDataSt sj = new WeatherDataSt();
sj.addObserver(current);
sj.addObserver(forcast);
sj.setData(22, 55, 88);
System.out.println("----");
sj.deleteObserver(forcast);
sj.setData(229, 559, 889);
}
}