观察者有什么用(Java观察者模式有什么用)

发布时间:2025-12-11 02:24:22 浏览次数:2

一、观察者模式的定义和特点

观察者模式的定义:

指多个对象间存在一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新。这种模式有时又称作发布-订阅模式、模型-视图模式,它是对象行为型模式。

特点:

1.降低了目标与观察者之间的耦合关系,两者之间是抽象耦合关系。符合依赖倒置原则。

2.目标与观察者之间建立了一套触发机制。

二、观察者模式的结构

实现观察者模式时要注意具体目标对象和具体观察者对象之间不能直接调用,否则将使两者之间紧密耦合起来,这违反了面向对象的设计原则。 观察者模式的主要角色如下。

Subject类:他把所有对观察者对象的引用保存在一个聚合里,每个主题都可以有任何数量的观察者,抽象主题提供一个接口,可以增加和删除任意的观察者对象

observer类:抽象观察者,为所有的具体观察者定义一个接口,在得到主题的通知时更新自己

ConcreteSubject:具体主题,将有关状态存入具体观察者对象,在具体主题的内部状态改变时,给所有登记过的的观察者发出通知

ConcreteObserver:具体观察者,实现抽象观察者角色所要求的的更新接口,以便使本身的状态与主题的状态向协调

三、代码实例

现在有一个需求,各网站需要订阅天气需求, 我们这边要及时更新并发送天气信息,且我们可以自由的注册或者移除想要发送的网站,用观察者模式实现。

如果我们用传统的模式实现该案例,那么会出现一个问题,就是如果我们要修改网站,那可能回去改动网站类的代码,和我们操作更新数据的代码,这不符合我们的开闭原则,因此我们采用观察者模式去实现,因为他也是一种一对多的依赖关系,生活中这种案例多不胜数,例如订阅杂志,等。

结构图如下

代码示例

抽象目标类Subject

packagecom.observerPattern.weatherCase;/***@authorwang*@version1.0*@packageNamecom.observerPattern.weatherCase*@classNameSubject*@date2021/12/2815:49*@DescriptionSubject抽象目标类,由具体的目标去实现*/publicinterfaceSubjectpackagecom.observerPattern.weatherCase;/***@authorwang*@version1.0*@packageNamecom.observerPattern.weatherCase*@classNameSubject*@date2021/12/2815:49*@DescriptionSubject抽象目标类,由具体的目标去实现*/publicinterfaceSubject{/***@Date2021/12/2816:20*@Param*@paramo*@Returnvoid*@MetodNameregisterObserver*@Authorwang*@Description注册观察者方法*/voidregisterObserver(Observero);/***@Date2021/12/2816:20*@Param*@paramo*@Returnvoid*@MetodNameremoveObserver*@Authorwang*@Description移除观察者*/voidremoveObserver(Observero);/***@Date2021/12/2816:20*@Param*@Returnvoid*@MetodNamenotifyObservers*@Authorwang*@Description通知观察者*/voidnotifyObservers();}

具体目标WeatherDate类

packagecom.observerPattern.weatherCase;importjava.util.ArrayList;/***@authorwang*@version1.0*@packageNamecom.observerPattern.weatherCase*@classNameWeatherDate*@date2021/12/2816:00*@Description包含最新的天气数据,是具体的目标,实现了抽象目标subject*该类含有观察者集合,使用ArrayLis集合管理.*当数据有更新时,就主动的调用ArrayList集合通知各个观察者**/publicclassWeatherDateimplementsSubject{privatefloattemperature;privatefloatpressure;privatefloathumidity;privateArrayList<Observer>observers;/***@Date2021/12/2816:10*@Param*@Returnnull*@MetodNameWeatherDate*@Authorwang*@Description初始化观察者集合*/publicWeatherDate(){this.observers=newArrayList<Observer>();}publicfloatgetTemperature(){returntemperature;}publicfloatgetPressure(){returnpressure;}publicfloatgetHumidity(){returnhumidity;}/***@Date2021/12/2816:10*@Param*@Returnvoid*@MetodNamedateChange*@Authorwang*@Description调用通知方法,将更新后的数据推送至各个观察者*/publicvoiddateChange(){notifyObservers();}/***@Date2021/12/2816:11*@Param*@paramtemperature*@parampressure*@paramhumidity*@Returnvoid*@MetodNamesetDate*@Authorwang*@Description更新数据*/publicvoidsetDate(floattemperature,floatpressure,floathumidity){this.temperature=temperature;this.pressure=pressure;this.humidity=humidity;dateChange();}/***@Date2021/12/2816:11*@Param*@paramo*@Returnvoid*@MetodNameregisterObserver*@Authorwang*@Descriptionz注册一个观察者*/@OverridepublicvoidregisterObserver(Observero){observers.add(o);}/***@Date2021/12/2816:11*@Param*@paramo*@Returnvoid*@MetodNameremoveObserver*@Authorwang*@Description移除一个观察者*/@OverridepublicvoidremoveObserver(Observero){if(observers.contains(o)){observers.remove(o);}}/***@Date2021/12/2816:12*@Param*@Returnvoid*@MetodNamenotifyObservers*@Authorwang*@Description通知观察者*/@OverridepublicvoidnotifyObservers(){for(inti=0;i<observers.size();i++){observers.get(i).update(this.temperature,this.pressure,this.humidity);}}}

抽象观察者Observer:

packagecom.observerPattern.weatherCase;/***@authorwang*@version1.0*@packageNamecom.observerPattern.weatherCase*@classNameObserver*@date2021/12/2815:50*@Description观察者接口,方法更新温度,压力,湿度,由具体的观察者实现*/publicinterfaceObserver{/***@Date2021/12/2816:18*@Param*@paramtemperature*@parampressure*@paramhumidity*@Returnvoid*@MetodNameupdate*@Authorwang*@Description*/voidupdate(floattemperature,floatpressure,floathumidity);}

具体观察者1

packagecom.observerPattern.weatherCase;/***@authorwang*@version1.0*@packageNamecom.observerPattern.weatherCase*@classNameCurrentCondition*@date2021/12/2815:54*@Description具体的一个观察者类,表示当前天气情况,实现观察者接口*/publicclassCurrentConditionimplementsObserver{privatefloattemperature;privatefloatpressure;privatefloathumidity;/***@Date2021/12/2815:58*@Param*@paramtemperature*@parampressure*@paramhumidity*@Returnvoid*@MetodNameupdate*@Authorwang*@Description该方法将更新后的数据推送至该观察者,观察者打印*/@Overridepublicvoidupdate(floattemperature,floatpressure,floathumidity){this.temperature=temperature;this.pressure=pressure;this.humidity=humidity;display();}/***@Date2021/12/2815:59*@Param*@Returnvoid*@MetodNamedisplay*@Authorwang*@Description该方法显示更新的数据*/publicvoiddisplay(){System.out.println("测试显示当前气温:"+temperature+"度");System.out.println("测试显示当前压力:"+pressure+"帕");System.out.println("测试显示当前湿度:"+humidity+"Rh");}}

具体观察者2:

packagecom.observerPattern.weatherCase;/***@authorwang*@version1.0*@packageNamecom.observerPattern.weatherCase*@classNameSinaNet*@date2021/12/2816:21*@Description新浪网站作为一个观察者*/publicclassSinaNetimplementsObserver{privatefloattemperature;privatefloatpressure;privatefloathumidity;/***@Date2021/12/2815:58*@Param*@paramtemperature*@parampressure*@paramhumidity*@Returnvoid*@MetodNameupdate*@Authorwang*@Description该方法将更新后的数据推送至该观察者,观察者打印*/@Overridepublicvoidupdate(floattemperature,floatpressure,floathumidity){this.temperature=temperature;this.pressure=pressure;this.humidity=humidity;display();}/***@Date2021/12/2815:59*@Param*@Returnvoid*@MetodNamedisplay*@Authorwang*@Description该方法显示更新的数据*/publicvoiddisplay(){System.out.println("=======新浪网站=======");System.out.println("新浪显示当前气温:"+temperature+"度");System.out.println("新浪显示当前压力:"+pressure+"帕");System.out.println("新浪显示当前湿度:"+humidity+"Rh");}}

客户端测试类

packagecom.observerPattern.weatherCase;/***@authorwang*@version1.0*@packageNamecom.observerPattern.weatherCase*@classNameClientTest*@date2021/12/2816:12*@Description客户端测试代码,测试观察者模式*/publicclassClientTest{publicstaticvoidmain(String[]args){//创建一个weatherDate具体目标WeatherDateweatherDate=newWeatherDate();//创建一个观察者CurrentConditioncurrentCondition=newCurrentCondition();//注册一个观察者weatherDate.registerObserver(currentCondition);//注册新浪SinaNetsinaNet=newSinaNet();weatherDate.registerObserver(sinaNet);//测试更新System.out.println("通知给各观察者");weatherDate.setDate(3,65,12);//测试移除weatherDate.removeObserver(currentCondition);System.out.println("========================");System.out.println("第二次更新");weatherDate.setDate(6,88,16);}}/*通知给各观察者测试显示当前气温:3.0度测试显示当前压力:65.0帕测试显示当前湿度:12.0Rh=======新浪网站=======新浪显示当前气温:3.0度新浪显示当前压力:65.0帕新浪显示当前湿度:12.0Rh========================第二次更新=======新浪网站=======新浪显示当前气温:6.0度新浪显示当前压力:88.0帕新浪显示当前湿度:16.0Rh*/

这种好处是我们如果有新的网站的加入,那么直接添加一个观察者类即可,不用修改代码

以及删除,注册都是独立开来的。

观察者有什么用
需要做网站?需要网络推广?欢迎咨询客户经理 13272073477