观察者模式:对象之间多对一依赖的一种设计方案,被依赖的对象为Subject,依赖的对象为Observer,Subject通知Observer变化java
生活中的例子就是:订报纸、顶牛奶dom
案例一:气象站 一个普通的方案: ide
气象站类测试
package com.java.test.internetweather; import java.util.Observable; public class WeatherData extends Observable { //气象站的信息 //温度气压湿度 private float mTemperatrue; private float mPressure; private float mHumidity; //外部接入的类 //公告板类 //须要得到气象站的这些信息,而且气象站的信息变化,也要跟着变 private CurrentConditions mCurrentConditions; //有参构造,须要传入公告板类 public WeatherData(CurrentConditions mCurrentConditions) { this. mCurrentConditions= mCurrentConditions; } //三个get方法 public float getTemperature() { return mTemperatrue; } public float getPressure() { return mPressure; } public float getHumidity() { return mHumidity; //处理数据变化,数据变化,也要把变化的数据传入公告板类,实现跟着变 } public void dataChange() { mCurrentConditions.update(this.getTemperature(),this.getPressure(),this.getHumidity()); } //设定数据 public void setData(float mTemperature,float mPressure,float mHumidity) { this.mTemperatrue=mTemperature; this.mPressure=mPressure; this.mHumidity=mHumidity; dataChange(); } } //公告板类 ```java package com.java.test.internetweather; public class CurrentConditions { //定义温度气压湿度 private float mTemperature; private float mPressure; private float mHumidity; //设定三个参数 public void update(float mTemperature,float mPressure,float mHumidity) { this.mTemperature=mTemperature; this.mPressure=mPressure; this.mHumidity=mHumidity; display(); } //展现数据,在控制台模拟 public void display() { System.out.println("***Today mTemperature: "+mTemperature+"***"); System.out.println("***Today mPressure: "+mPressure+"***"); System.out.println("***Today mHumidity: "+mHumidity+"***"); } } //测试类 ```java package com.java.test.internetweather; public class InternetWeather { public static void main(String[] args) { CurrentConditions mCurrentConditions; WeatherData mWeatherData; mCurrentConditions=new CurrentConditions(); mWeatherData=new WeatherData(mCurrentConditions); mWeatherData.setData(30, 150, 40); } }
这种方式耦合性仍是过高this
观察者模式设计方案 设计
Subject接口类code
package com.java.test.internetweather.observer; public interface Subject { public void registerObserver(Observer o); public void removeObserver(Observer o); public void notifyObservers(); }
Observerserver
package com.java.test.internetweather.observer; public interface Observer { public void update(float mTemperatrue,float mPressure,float mHumidity); }
公告牌一 CurrentConditions对象
package com.java.test.internetweather.mode; import com.java.test.internetweather.observer.Observer; public class CurrentConditions implements Observer { /*私有变量*/ private float mTemperatrue; private float mPressure; private float mHumidity; @Override public void update(float mTemperatrue, float mPressure, float mHumidity) { // TODO Auto-generated method stub this.mHumidity = mHumidity; this.mPressure = mPressure; this.mTemperatrue = mTemperatrue; display(); } public void display() { System.out.println("***Today mTemperatrue:" + mTemperatrue + "***"); System.out.println("***Today mPressure:" + mPressure + "***"); System.out.println("***Today mHumidity:" + mHumidity + "***"); } }
公告牌二 ForcastConditionsblog
package com.java.test.internetweather.mode; import com.java.test.internetweather.observer.Observer; public class ForcastConditions implements Observer{ private float mTemperatrue; private float mPressure; private float mHumidity; @Override public void update(float mTemperatrue, float mPressure, float mHumidity) { // TODO Auto-generated method stub this.mTemperatrue=mTemperatrue; this.mPressure=mPressure; this.mHumidity=mHumidity; display(); } public void display() { System.out.println("**明天温度:"+(mTemperatrue+Math.random())+"**"); System.out.println("**明天气压:"+(mPressure+10*Math.random())+"**"); System.out.println("**明天湿度:"+(mHumidity+Math.random())+"**"); } }
测试类 InternetWeather
package com.java.test.internetweather.mode; public class InternetWeather { public static void main(String[] args) { CurrentConditions mCurrentConditions; ForcastConditions mForcastConditions; WeatherDataSt mWeatherDataSt; mWeatherDataSt=new WeatherDataSt(); mCurrentConditions=new CurrentConditions(); mForcastConditions=new ForcastConditions(); mWeatherDataSt.registerObserver(mCurrentConditions); mWeatherDataSt.registerObserver(mForcastConditions); mWeatherDataSt.setData(30, 150, 40); mWeatherDataSt.removeObserver(mCurrentConditions); mWeatherDataSt.setData(40, 250, 50); } }
观察者模式实现了比较好的低耦合特性,Object和Observer之间的关系只有实现了update方法这一关系,耦合性很是低
Java内置了观察者对象 Observable Observer
Subject
WeatherData
package com.java.test.internetweather.jv; import java.util.Observable; public class WeatherData extends Observable{ private float mTemperatrue; private float mPressure; private float mHumidity; public float getTemperature() { return mTemperatrue; } public float getPressure() { return mPressure; } public float getHumidity() { return mHumidity; } public void dataChange() { //表示数据变化了 //从源码中能够看到里面有个bool值变为了true,下面那个方法会判断这个是否为true this.setChanged(); //这个方式是等观察者本身拉取 //this.notifyObservers(); //这个方式是把信息主动推送给观察者 this.notifyObservers(new Data(getTemperature(),getPressure(),getHumidity())); } public void setData(float mTemperatrue,float mPressure,float mHumidity) { this.mTemperatrue=mTemperatrue; this.mPressure=mPressure; this.mHumidity=mHumidity; dataChange(); } public class Data { public float mTemperatrue; public float mPressure; public float mHumidity; public Data(float mTemperatrue,float mPressure,float mHumidity) { this.mTemperatrue=mTemperatrue; this.mPressure=mPressure; this.mHumidity=mHumidity; } } }
公告板一
package com.java.test.internetweather.jv; import java.util.Observable; import java.util.Observer; import com.java.test.internetweather.jv.WeatherData.Data; public class CurrentConditions implements Observer { private float mTemperatrue; private float mPressure; private float mHumidity; @Override public void update(Observable arg0, Object arg1) { // TODO Auto-generated method stub this.mTemperatrue=((Data)(arg1)).mTemperatrue; this.mPressure=((Data)(arg1)).mPressure; this.mHumidity=((Data)(arg1)).mHumidity; display(); } public void display() { System.out.println("***Today mTemperatrue:" +mTemperatrue+"***"); System.out.println("***Today mPressure:" +mPressure+"***"); System.out.println("***Today mHumidity:" +mHumidity+"***"); } }
公告板二 ForcastConditions
package com.java.test.internetweather.mode; import com.java.test.internetweather.observer.Observer; public class ForcastConditions implements Observer{ private float mTemperatrue; private float mPressure; private float mHumidity; @Override public void update(float mTemperatrue, float mPressure, float mHumidity) { // TODO Auto-generated method stub this.mTemperatrue=mTemperatrue; this.mPressure=mPressure; this.mHumidity=mHumidity; display(); } public void display() { System.out.println("**明天温度:"+(mTemperatrue+Math.random())+"**"); System.out.println("**明天气压:"+(mPressure+10*Math.random())+"**"); System.out.println("**明天湿度:"+(mHumidity+Math.random())+"**"); } }
测试类
package com.java.test.internetweather.jv; public class InternetWeather { public static void main(String[] args) { CurrentConditions mCurrentConditions; ForcastConditions mForcastConditions; WeatherData mWeatherData; mCurrentConditions=new CurrentConditions(); mForcastConditions=new ForcastConditions(); mWeatherData=new WeatherData(); mWeatherData.addObserver(mCurrentConditions); mWeatherData.addObserver(mForcastConditions); mWeatherData.setData(30, 150, 40); mWeatherData.deleteObserver(mCurrentConditions); mWeatherData.setData(35, 150, 60); } }