经验首页 前端设计 程序设计 Java相关 移动开发 数据库/运维 软件/图像 大数据/云计算 其他经验
当前位置:技术经验 » Java相关 » 设计模式 » 查看文章
JAVA设计模式之观察者模式 - Observer - J-Simon
来源:cnblogs  作者:J-Simon  时间:2019/5/27 8:52:19  对本文有异议

有趣的事情发生时,可千万别错过了!有一个模式可以帮你的对象知悉现况,不会错过该对象感兴趣的事。对象甚至在运行时可决定是否要继续被通知。有了观察者,你将会消息灵通。

介绍

观察者模式的定义:

  1. 在对象之间定义一对多的依赖,这样一来,当一个对象改变状态,依赖它的对象都会收到通知,并自动更新。

简单理解

为了方便理解观察者模式,我们以报社为例:

  1. 报社的业务是出版报纸;
  2. 向某家报社订阅报纸,只要他们有新报纸出版,就会给你送来。只要你是他们的订户,你就会一直收到新报纸。
  3. 当你不想再看报纸的时候,取消订阅,他们就不会再送新报纸来。
  4. 只要报社还在运营,就会一直有人(或单位)

如果你了解报社的订阅是怎么回事,其实就知道观察者是怎么回事了,只是名称不太一样:
出版者改称为“主题”(Subject)或“被观察者”(Observable),订阅者改称为“观察者”(Observer).
主题 + 观察者 = 观察者模式
主题就是定义中的“一”,观察者为定义中的“多”,当主题有变化时,便会通知它的”订阅者“也就是”观察者“

使用场景

  • 一个抽象模型有两个方面,其中一个方面依赖于另一个方面。将这些方面封装在独立的对象中使它们可以各自独立地改变和复用。
  • 一个对象的改变将导致其他一个或多个对象也发生改变,而不知道具体有多少对象将发生改变,可以降低对象之间的耦合度。
  • 一个对象必须通知其他对象,而并不知道这些对象是谁。
  • 需要在系统中创建一个触发链,A对象的行为将影响B对象,B对象的行为将影响C对象……,可以使用观察者模式创建一种链式触发机制。

举例:有一个微信公众号服务,不定时发布一些消息,关注公众号就可以收到推送消息,取消关注就收不到推送消息。

优缺点

优点

  1. 观察者和被观察者是抽象松耦合的;
  2. 建立一套触发机制。

缺点

  1. 如果一个被观察者对象有很多的直接和间接的观察者的话,将所有的观察者都通知到会花费很多时间;
  2. 如果在观察者和观察目标之间有循环依赖的话,观察目标会触发它们之间进行循环调用,可能导致系统崩溃。

注意事项

  1. JAVA 中已经有了对观察者模式的支持类;
  2. 避免循环引用;
  3. 如果顺序执行,某一观察者错误会导致系统卡壳,一般采用异步方式。

实现

类图

实现步骤

创建抽象主题 - Subject

  1. public interface Subject {
  2. //观察者订阅服务
  3. public void registerObserver(Observer o);
  4. //观察者取消订阅服务
  5. public void removeObserver(Observer o);
  6. //主题改变时,会被调用,通知所有观察者
  7. public void notifyObservers();
  8. }

创建抽象观察者 - Observer

  1. public interface Observer {
  2. public void update(float temp, float humidity, float pressure);
  3. }

创建具体主题

  1. public class WeatherData implements Subject {
  2. private ArrayList<Observer> observers;
  3. private float temperature;
  4. private float humidity;
  5. private float pressure;
  6. public WeatherData() {
  7. observers = new ArrayList<Observer>();
  8. }
  9. public void registerObserver(Observer o) {
  10. observers.add(o);
  11. }
  12. public void removeObserver(Observer o) {
  13. int i = observers.indexOf(o);
  14. if (i >= 0) {
  15. observers.remove(i);
  16. }
  17. }
  18. public void notifyObservers() {
  19. for (Observer observer : observers) {
  20. observer.update(temperature, humidity, pressure);
  21. }
  22. }
  23. public void measurementsChanged() {
  24. notifyObservers();
  25. }
  26. public void setMeasurements(float temperature, float humidity, float pressure) {
  27. this.temperature = temperature;
  28. this.humidity = humidity;
  29. this.pressure = pressure;
  30. measurementsChanged();
  31. }
  32. // public float getTemperature() {
  33. // return temperature;
  34. // }
  35. //
  36. // public float getHumidity() {
  37. // return humidity;
  38. // }
  39. //
  40. // public float getPressure() {
  41. // return pressure;
  42. // }
  43. }

创建一个具体观察者

  1. public class CurrentConditionsDisplay implements Observer {
  2. private float temperature;
  3. private float humidity;
  4. private Subject weatherData;
  5. public CurrentConditionsDisplay(Subject weatherData) {
  6. this.weatherData = weatherData;
  7. //订阅
  8. weatherData.registerObserver(this);
  9. }
  10. public void update(float temperature, float humidity, float pressure) {
  11. this.temperature = temperature;
  12. this.humidity = humidity;
  13. display();
  14. }
  15. public void display() {
  16. System.out.println("Current conditions: " + temperature
  17. + "F degrees and " + humidity + "% humidity");
  18. }
  19. }

测试

  1. public class WeatherStation {
  2. public static void main(String[] args) {
  3. //创建主题
  4. WeatherData weatherData = new WeatherData();
  5. //创建观察者并订阅
  6. CurrentConditionsDisplay currentDisplay = new CurrentConditionsDisplay(weatherData);
  7. // StatisticsDisplay statisticsDisplay = new StatisticsDisplay(weatherData);
  8. // ForecastDisplay forecastDisplay = new ForecastDisplay(weatherData);
  9. //通知观察者
  10. weatherData.setMeasurements(80, 65, 30.4f);
  11. // weatherData.setMeasurements(82, 70, 29.2f);
  12. // weatherData.setMeasurements(78, 90, 29.2f);
  13. }
  14. }

结语

设计模式源于生活

原文链接:http://www.cnblogs.com/J-Simon/p/10926728.html

 友情链接:直通硅谷  点职佳  北美留学生论坛

本站QQ群:前端 618073944 | Java 606181507 | Python 626812652 | C/C++ 612253063 | 微信 634508462 | 苹果 692586424 | C#/.net 182808419 | PHP 305140648 | 运维 608723728

W3xue 的所有内容仅供测试,对任何法律问题及风险不承担任何责任。通过使用本站内容随之而来的风险与本站无关。
关于我们  |  意见建议  |  捐助我们  |  报错有奖  |  广告合作、友情链接(目前9元/月)请联系QQ:27243702 沸活量
皖ICP备17017327号-2 皖公网安备34020702000426号