观察者模式 你的名字 2022-02-01 13:53 403阅读 0赞 # 什么是观察者模式? # **简单的来说,观察者模式=出版者+订阅者。**用比较书面的话来说的话是:定义了对象之间的一对多依赖,当一所对应的对象状态改变时,它的所有依赖者都会收到通知并自动更新,现在不理解这个定义完全没事,下面我将慢慢讲解。 现在假定有一个需求,气象站需要对天气进行监测,使用三个气象传感器,监测传感器(获取实际气象数据的物理装置)、接收数据传感器(接收来自气象站气象数据,并更新到布告显示传感器)、布告显示传感器(显示数据)。 ![watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzI1OTMzMjQ5_size_16_color_FFFFFF_t_70][] 因为接收传感器与监测传感器取的联系,并把数据给布告显示传感器进行显示,所以我们可以把它直接抽象为WeatherData对象。 瞧一瞧刚送到WeatherData类 ![watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzI1OTMzMjQ5_size_16_color_FFFFFF_t_70 1][] 那么目前我们知道些什么 呢? 1. WeatherData类具有getter方法,可取得三个测量值:温度、湿度、压力 2. 当新的测量数据备妥时,measuementsChanged()方法就会被调用 3. 我们可能有其他需求,比如,需要显示气象统计的布告,天气预告的布告。一旦WeatherData有新的测量,这些布告必须马上更新。 4. 此系统必须是可扩展,可以随着需求的变化,随时增加和减少布告板 下面我们来看一下错误示例 public class WeatherData{ public void measurementsChanged(){ float temp = getTemperature(); float humidity = getHumidity(); float pressure = getPressure(); currentConditionsDisplay.update(temp,humidity,pressure); statisticsDisplay.update(temp,humidity,pressure); forecastDisplay.update(temp,humidity,pressure); } .....//其他方法 } 本例是针对具体编程,会导致我们以后在增加或删除布告板时必须要修改程序,灵活性比较低。 # 认识观察者模式 # 我们看看报纸和杂志的订阅是怎么回事? 1. 报社的业务就是出版报纸 2. 向某家报社订阅报纸,只要他们有新报纸出版,就会给你送来。 3. 当你不想再看报纸的时候,取消订阅,报社就不会再送报纸来 4. 只要报社还再运营,就会一直有人订阅报纸或取消订阅。 # 出版者+订阅者=观察者模式 # 如果你看懂了上面的报纸和杂志的订阅关系,你就知道观察者模式大概是怎么回事了。我们现在把出版者改称为主题(subject),订阅者改称为观察者(observer) # 定义观察者模式 # 当你试图想要了解观察者模式时,可以使用报纸订阅模式尝试着去理解观察者模式的大致流程。 观察者模式,用书面的定义通常是: **观察者模式**定义了对象之间一对多依赖,这样一来,当一个对象改变状态时,它的所有依赖者都会收到通知并自动更新。 ![watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzI1OTMzMjQ5_size_16_color_FFFFFF_t_70 2][] 报社和订阅者定义了一对多的关系。订阅者依赖于报社,只要报社一有新的新闻,就会想订阅者推送新闻。类比只要主题状态发生改变,就会通知观察者进行更新。 ![watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzI1OTMzMjQ5_size_16_color_FFFFFF_t_70 3][] 1. Subject:这是主题接口,对象使用此接口对观察者进行增加或删除。 2. ConcreteSubject:具体主题实现主题接口,除了注册和移除观察者,还有主题状态发生改变时notifyObjecter()通知所有观察者更新状态。 3. Observer:观察者接口 4. ConcreteObserver:具体观察可以是实现此接口的任意类,必须注册到主题中,当主题状态发生改变时,以便接收更新。 观察者模式,主题时具有状态的对象,并且可以控制这些状态,也就是说,是一个具有状态的主题。另一方面,观察者使用这些状态,虽然这些状态并不属于他们,有许多观察者依赖主题来告诉他们状态何时改变了。这就产生一个关系:一个主题对多个观察者的关系。 下面我们来设计气象监测 URM图如下: ![watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzI1OTMzMjQ5_size_16_color_FFFFFF_t_70 4][] Subject接口:是我们的主题接口。 public interface Subject { //注册观察者 public void registerObserver(Observer o); //移除观察者 public void removeObserver(Observer o); //通知观察者 public void notifyObservers(); } Observer接口:观察者接口,所有的气象组件观察者都要实现该接口 public interface Observer { public void update(float temp,float humidity,float pressure); } DisplayElement接口:为布告板提供接口,实现显示数据功能 public interface DisplayElement { public void display(); } WeatherData:实现Sbject主题接口。 public class WeatherData implements Subject{ private ArrayList observers; private float temperature; private float humidity; private float pressure; public WeatherData() { this.observers = new ArrayList(); } @Override public void registerObserver(Observer o) { observers.add(o); } @Override public void removeObserver(Observer o) { int index = observers.indexOf(o); if (index>=0){ observers.remove(index); } } @Override public void notifyObservers() { for (int i = 0;i<observers.size();i++){ Observer observer = (Observer) observers.get(i); observer.update(temperature,humidity,pressure); } } public void measurementsChanged(){ notifyObservers(); } public void setMeasurements(float temperature,float humidity,float pressure){ this.temperature = temperature; this.humidity = humidity; this.pressure = pressure; measurementsChanged(); } } CurrentConditionDisplay:根据WeatherData更新和显示气象监测数据。 public class CurrentConditionDisplay implements Observer,DisplayElement{ private float temperature; private float humidity; private Subject weatherData; public CurrentConditionDisplay(Subject weatherData) { this.weatherData = weatherData; weatherData.registerObserver(this); } @Override public void display() { System.out.println("Current conditions: "+temperature+" F degrees and "+humidity); } @Override public void update(float temp, float humidity, float pressure) { this.temperature=temp; this.humidity = humidity; display(); } } StatisticsDisplay、ForcastDisplay、ThirdPartDisplay类分别根据WeatherData的监测的气象数据统计气象数据并显示、预测气象数据并显示、显示其他数据。具体我们不用关心。 最终测试 public class Test01 { public static void main(String[] args) { WeatherData weatherData = new WeatherData(); CurrentConditionDisplay currentConditionDisplay = new CurrentConditionDisplay(weatherData); weatherData.setMeasurements(80,65,30.4f); } } 控制台显示:Current conditions: 80.0 F degrees and 65.0 其实在JDK中也内置观察者模式接口,就是java.util.Observer接口,大家有兴趣可以就研究研究。 [watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzI1OTMzMjQ5_size_16_color_FFFFFF_t_70]: /images/20220201/3aa5df9390c34104bdd1d2294307a9eb.png [watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzI1OTMzMjQ5_size_16_color_FFFFFF_t_70 1]: /images/20220201/1f3dd51e365b4b3dbdd66b0497d46d48.png [watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzI1OTMzMjQ5_size_16_color_FFFFFF_t_70 2]: /images/20220201/9c6d19c9d38e4f0c96beac9ede291e2d.png [watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzI1OTMzMjQ5_size_16_color_FFFFFF_t_70 3]: /images/20220201/26bb5a2b2ecc42928544be78a7e87b76.png [watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzI1OTMzMjQ5_size_16_color_FFFFFF_t_70 4]: /images/20220201/df3168f1c6724904a68f7660f1a2e62a.png
相关 观察者模式 什么是观察者模式 有人这么说 > 观察者模式定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象。 > > 这个主题对象在状态上发生变化时,会通知所有观 梦里梦外;/ 2022年07月20日 12:05/ 0 赞/ 282 阅读
相关 观察者模式 观察者模式:定义了对象之间的一对多的依赖,这样一来,当一个对象改变状态时,它的所有依赖者都会收到通知并自动更新。 观察者模式图: ![输入图片说明][13105107_Mf 旧城等待,/ 2022年06月03日 02:41/ 0 赞/ 276 阅读
相关 观察者模式 前言 观察者模式还算一个比较好玩的设计模式,其实就是发布订阅模式,发布者发布信息,订阅者获取信息,订阅了就能收到信息,没订阅就收不到信息。可以想象成消息中间件在系统中的作 墨蓝/ 2022年03月15日 06:48/ 0 赞/ 329 阅读
相关 观察者模式 类似于广播,目标对象的状态改变后,所有观察者的状态随之改变 步骤: 目标类中有一个属性是一个集合, 有一个注册方法,所有观察者使用前都要注册。 有一个 ╰半橙微兮°/ 2022年02月01日 15:43/ 0 赞/ 250 阅读
相关 观察者模式 什么是观察者模式? 简单的来说,观察者模式=出版者+订阅者。用比较书面的话来说的话是:定义了对象之间的一对多依赖,当一所对应的对象状态改变时,它的所有依赖者都会收到通知并 你的名字/ 2022年02月01日 13:53/ 0 赞/ 404 阅读
相关 观察者模式 前言 观察者模式又叫发布-订阅(Publish/Subscribe)模式 观察者模式定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象。这个 本是古典 何须时尚/ 2021年12月09日 00:47/ 0 赞/ 356 阅读
相关 观察者模式 case ![18721752-ed32bda3ae538d1f.png][] image.png 非设计模式code SimpleWeatherDat 朱雀/ 2021年09月18日 07:26/ 0 赞/ 466 阅读
相关 观察者模式 当对象间存在一对多关系时,则使用观察者模式(Observer Pattern)。比如,当一个对象被修改时,则会自动通知它的依赖对象。观察者模式属于行为型模式。 意图:定义对象 系统管理员/ 2021年09月17日 01:36/ 0 赞/ 488 阅读
相关 观察者模式 15.观察者模式 ![70][] public abstract class Blog// 订阅号抽象类 { priva 布满荆棘的人生/ 2021年09月17日 00:04/ 0 赞/ 458 阅读
相关 观察者模式 一 点睛 定义 又被称为发布-订阅(Publish/Subscribe)模式,它定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象。这个主题对象在状态 ﹏ヽ暗。殇╰゛Y/ 2021年07月24日 14:52/ 0 赞/ 479 阅读
还没有评论,来说两句吧...