观察者模式浅谈篇(一)

来源:互联网 发布:淘宝全屏热点代码 编辑:程序博客网 时间:2024/06/05 12:23

观察者模式浅谈篇(一)

     上一篇博客讲解了数据库的观察者模式,相必大家和我一样其他地方也有需要使用该模式的,下面我将分步骤和大家一起学习观察者模式,观察者模式是JDK中使用较多的模式,比较简单易懂。

【附件:http://blog.csdn.net/qq_34071798/article/details/53427522(数据库观察者模式使用)

   下面我举一个生活中典型的观察者模式的栗子:

                                                            

    看图中:报社就相当于我们观察者模式中的“被观察者”,用户1,用户2,用户...,就相当于我们的观察者,当被报社有了新的报纸,派递员就会派送给所有订阅它的用户,用户不用管报纸怎么生产,新闻怎么来这些细节。【观察者模式定义:对象之间的一对多依赖,这样一来,当一个对象状态改变时,它所有依赖者都会收到通知并自动更新】。

       下面我们就进入实战,以下是项目需求

    气象站需要制作一个有关天气的APP,他们会提供一个更新(温度,湿度,气压等等的接口【记住这里的数据参数是不确定的】)

                     

现在我们先分析:

第一步:首先气象站这一边我们不用考虑,因为数据是定时推送过来,和我们的业务关系不大。

第二步:我们主要是实现【被观察者这个类(subject)】逻辑处理也主要是在这个类中。

第三步:我们生成观察者类【observer】,用于收到“被观察者”的数据更新后,用于数据展示。

大致我们可以知道我们至少要有三个抽象类:                 

注解:

WeatherData{【天气数据类】,(measurementChange方法)【天气站数据更新逻辑处理后同步给观察者的方法】,(registerObject方法)【注册观察者】,(removerObject方法)【移除观察者】,(notifiObserver方法)【通知所有观察者】}

CurrentConditionsDisplay{【数据展示类】,(update方法)【同步被观察者同步过来的数据】,

display方法)【展示新数据】}

代码实现讲解:

//抽象类这里就不展示了 还是以上接口

import java.util.ArrayList;public class WeatherData implements Subject {// 装所有观察者的容器private ArrayList<Observer> mArrObserver = null;// 天气数据类private WeatherBean mWeatherBean = null;// 是否更新了数据【这个变量我们后期可以限制多久推送给订阅者数据】private boolean mIsNotifichange = false;public WeatherData() {mArrObserver = new ArrayList<Observer>();}// 注册观察者public final void registerObserver(Observer obj) {if (obj != null && mArrObserver != null&& -1 == mArrObserver.indexOf(obj)) {// arryList中没有该对象则返回-1mArrObserver.add(obj);// 打印类 与项目无关SystemUtils.SystemMian("registerObserver() over: arrObserver.size()"+ mArrObserver.size());}}// 移除观察者public final void removeObserver(Observer obj) {if (obj != null && mArrObserver != null&& -1 != mArrObserver.indexOf(obj)) {int size = mArrObserver.indexOf(obj);mArrObserver.remove(size);SystemUtils.SystemMian("removeObserver() over: size:" + size+ ",arrObserver.size():" + mArrObserver.size());}}// 通知所有观察者public final void notifiObservers() {SystemUtils.SystemMian("notifiObservers() mArrObserver.size():"+mArrObserver.size());if (mArrObserver != null) {for (Observer obj : mArrObserver) {if (mIsNotifichange) {obj.update(mWeatherBean);}mIsNotifichange = false;}}}// 设置天气数据public void setMeasurement(Object obj) {WeatherBean weatherBean = mWeatherBean;if (obj instanceof WeatherBean) {mWeatherBean = (WeatherBean) obj;}MeasurementChange(weatherBean);}// 天气数据改变private void MeasurementChange(WeatherBean lastWeatherBean) {if (lastWeatherBean == null || !lastWeatherBean.equals(mWeatherBean)) {SystemUtils.SystemMian("MeasurementChange() WeatherBean mWeatherBean:"+mWeatherBean.toString());mIsNotifichange = true;notifiObservers();} else {SystemUtils.SystemMian("MeasurementChange() WeatherBean is Same");mIsNotifichange = false;}}public static class WeatherBean {float temp;float humidity;float pressure;public WeatherBean(float temp, float humidity, float pressure) {this.temp = temp;this.humidity = humidity;this.pressure = pressure;}@Overridepublic int hashCode() {final int prime = 31;int result = 1;result = prime * result + Float.floatToIntBits(humidity);result = prime * result + Float.floatToIntBits(pressure);result = prime * result + Float.floatToIntBits(temp);return result;}@Overridepublic boolean equals(Object obj) {if (this == obj)return true;if (obj == null)return false;if (getClass() != obj.getClass())return false;WeatherBean other = (WeatherBean) obj;if (Float.floatToIntBits(humidity) != Float.floatToIntBits(other.humidity))return false;if (Float.floatToIntBits(pressure) != Float.floatToIntBits(other.pressure))return false;if (Float.floatToIntBits(temp) != Float.floatToIntBits(other.temp))return false;return true;}@Overridepublic String toString() {return "WeatherBean [temp=" + temp + ", humidity=" + humidity+ ", pressure=" + pressure + "]";}}}

public class CurrentConditionsDisplay implements Observer, DisplayElement {//保存被观察者主要是用去注册 和解除注册操作private Subject mSu;//天气数据类private WeatherData.WeatherBean mWeatherBean = null;public CurrentConditionsDisplay(Subject su) {this.mSu = su;mSu.registerObserver(this);}//数据展示public void display() {SystemUtils.SystemMian("display()");if (mWeatherBean != null) {SystemUtils.SystemMian(mWeatherBean.toString());}}//数据已更新public void update(Object obj) {SystemUtils.SystemMian("CurrentConditionsDisplay update()");if (obj instanceof WeatherData.WeatherBean) {mWeatherBean = (WeatherData.WeatherBean) obj;display();}}}


public class DemoMain {public static void main(String[] args) {WeatherData weat = new WeatherData();CurrentConditionsDisplay currentConditionsDisplay = new CurrentConditionsDisplay(weat);weat.setMeasurement(new WeatherData.WeatherBean(11, 12, 13));}}

//下面是打印结果:


总结:从打印结果看出我们完成了订阅者的注册,以及数据更新后数据的同步。

步骤:1,建立被订阅者(订阅接口,取消订阅接口,数据更新通知接口)

            2,建立订阅者

比较简单,此刻的你看了或许高兴的认为“妈妈再也不用担心我的观察者模式了”。是的简单的观察者模式就这么简单,但是如果涉及到多线层以及多进程那样我们怎么操作呢?以及Java Utils中的观察者模式有何不同,请关注我第二篇观察者模式分析。以上观察者模式代码有优化处我也将在第二篇章提出来!!!

谢谢品读!!




0 0
原创粉丝点击