当前位置:   article > 正文

Java行为型设计模式-观察者模式

Java行为型设计模式-观察者模式

46018acdc4c8443fbbb03e1541a51693.png

1. 观察者模式简介

观察者模式(Observer Pattern)是行为型设计模式之一,它定义了一种一对多的依赖关系,让多个观察者对象同时监听某一主题对象。这个主题对象在状态发生变化时,会通知所有观察者对象,使它们能够自动更新自己。

在Java中,观察者模式通常通过java.util.Observable类和java.util.Observer接口实现,但是由于Observable类的方法都是同步的,可能会影响程序的灵活性和并发性,因此在Java 1.0版本之后,推荐使用Java.util.concurrent包下的BlockingQueue作为替代方案。

2. 观察者模式角色

89005d95a4e84fdd89fb5a5b463ce5dd.png

在Java中,观察者模式通常涉及到以下几个角色:

 2.1 Subject(目标)

 目标是被观察的对象。它提供了添加、删除观察者的接口,并在自身内部状态改变时通知观察者。

2.2 Observer(观察者)

观察者接口定义了一个更新方法,当目标的状态发生改变时,观察者会接收到通知并调用这个方法。

2.3 ConcreteSubject(具体目标)

实现了Subject的具体类,包含有关状态的通知方法。

2.4 ConcreteObserver(具体观察者)

实现了Observer接口的具体类,包含一个更新方法,当收到通知时会执行这个方法。 

3. 观察者模式应用场景

7affc015780743f99ec08d57956fcacb.png

观察者模式的应用场景非常广泛,主要包括‌:

‌3.1 发布-订阅系统‌

观察者模式是发布-订阅模式的核心。当发布者发布新消息或事件时,所有订阅者都会收到通知并执行相应的操作‌。

‌3.2 事件处理机制‌

观察者模式用于处理事件驱动的编程。事件触发时,事件源对象会通知事件处理程序(观察者),以执行相应的操作‌。

‌3.3 实时数据更新‌

在需要实时更新数据的应用中,观察者模式可以用于将数据源与数据消费者连接起来。当数据源的数据发生变化时,观察者可以自动获取最新的数据进行处理‌。

3.4 ‌库和框架‌

许多编程库和框架使用观察者模式来支持插件和扩展。开发人员可以编写自定义观察者以响应库或框架中的事件或回调‌。

‌3.5 消息队列系统‌

观察者模式可用于消息队列系统,其中生产者将消息发送到队列,而消费者作为观察者订阅队列以接收和处理消息‌。

3.6 ‌股票市场监测‌

股票市场应用程序可以使用观察者模式来监测股票价格变化,并将这些变化通知给投资者‌。

3.7 ‌游戏开发‌

在游戏中,观察者模式可用于处理各种事件,如玩家输入、碰撞检测、角色状态变化等‌。

3.8 ‌网络通信‌

在网络应用中,观察者模式可用于实现即时通信系统,其中用户之间的消息传递可以通过观察者模式来实现‌。

3.9 MVC架构设计

其中模型(Model)可以对应观察者模式中的观察目标,而视图(View)对应于观察者,控制器(Controller)则是中介者模式的应用场景之一‌。

4. 观察者模式优缺点

观察者模式在设计和实现对象间的动态一对多关系时非常有用,有诸多优点,尤其是在需要避免紧耦合的场景中。然而,使用时需要注意上述优缺点,以确保系统的稳定性和效率‌。

4.1 观察者模式的优点

  1. 解耦‌:观察者模式允许被观察者(主题)和观察者之间建立一种抽象的耦合关系,而不是紧密的依赖关系。这意味着被观察者不需要知道具体的观察者是谁,只需要知道它们都符合一个共同的接口。这种解耦使得被观察者和观察者可以独立变化,互不影响‌。
  2. 灵活性‌:基于接口的设计使得观察者模式具有很高的灵活性。可以灵活地添加新的观察者或改变观察者的行为,而不需要修改被观察者的代码。这种灵活性为程序提供了更大的设计空间‌。
  3. 维护一致性‌:通过建立松散的依赖关系,观察者模式有助于维护系统的一致性。当被观察者的状态发生变化时,所有依赖于此状态的观察者都会得到通知并进行更新,从而保持系统的一致性‌。

4.2 观察者模式缺点

  1. 过多的通知‌:当被观察者对象有很多直接和间接的观察者时,每次状态变化都需要通知所有观察者,这可能会花费很多时间,尤其是在有大量观察者的情况下,可能会影响程序的执行效率‌。
  2. 循环依赖问题‌:如果观察者和被观察者之间存在循环依赖,可能会导致系统崩溃。在使用观察者模式时,需要特别注意这一点,以避免出现循环调用的情况‌。
  3. 开发调试复杂‌:应用观察者模式时,需要考虑开发小路问题,包括被观察者和多个观察者的管理和调试,这可能会增加开发的复杂性‌。
  4. 没有提供变化细节‌:观察者模式只能让观察者知道被观察对象的变化,但不能提供关于变化的具体细节,这意味着观察者只能知道发生了变化,但不知道是如何变化的‌。

5. 观察者模式代码示例

      25229fb3d26a435cbe3bf6f9ab2eff5f.png  

以下是一个简单的观察者模式的实现:

  1. // 观察者接口
  2. interface Observer {
  3. void update(float temp, float humidity, float pressure);
  4. }
  5. // 目标接口
  6. interface Subject {
  7. void registerObserver(Observer o);
  8. void removeObserver(Observer o);
  9. void notifyObservers();
  10. }
  11. // 具体目标类
  12. class WeatherData implements Subject {
  13. private ArrayList<Observer> observers;
  14. private float temperature;
  15. private float humidity;
  16. private float pressure;
  17. public WeatherData() {
  18. observers = new ArrayList<>();
  19. }
  20. @Override
  21. public void registerObserver(Observer o) {
  22. observers.add(o);
  23. }
  24. @Override
  25. public void removeObserver(Observer o) {
  26. int i = observers.indexOf(o);
  27. if (i >= 0) {
  28. observers.remove(i);
  29. }
  30. }
  31. @Override
  32. public void notifyObservers() {
  33. for (Observer observer : observers) {
  34. observer.update(temperature, humidity, pressure);
  35. }
  36. }
  37. // 当获取到新的测量数据时,通知观察者
  38. public void measurementsChanged() {
  39. notifyObservers();
  40. }
  41. public void setMeasurements(float temperature, float humidity, float pressure) {
  42. this.temperature = temperature;
  43. this.humidity = humidity;
  44. this.pressure = pressure;
  45. measurementsChanged();
  46. }
  47. }
  48. // 具体观察者类
  49. class CurrentConditionsDisplay implements Observer {
  50. private float temperature;
  51. private float humidity;
  52. @Override
  53. public void update(float temp, float humidity, float pressure) {
  54. this.temperature = temp;
  55. this.humidity = humidity;
  56. display();
  57. }
  58. public void display() {
  59. System.out.println("Current conditions: " + temperature + "F degrees and " + humidity + "% humidity");
  60. }
  61. }
  62. // 使用观察者模式的示例
  63. public class WeatherStation {
  64. public static void main(String[] args) {
  65. WeatherData weatherData = new WeatherData();
  66. CurrentConditionsDisplay currentDisplay = new CurrentConditionsDisplay();
  67. weatherData.registerObserver(currentDisplay);
  68. // 当气象测量更新时,观察者会接收到通知
  69. weatherData.setMeasurements(80, 65, 30.4f);
  70. }
  71. }

在这个例子中,WeatherData类实现了Subject接口,负责存储气象数据,并在数据更新时通知观察者。CurrentConditionsDisplay类实现了Observer接口,用于显示当前的气象状况。当WeatherData的气象数据更新时,它会调用measurementsChanged()方法,通知所有注册的观察者。观察者接收到通知后,会调用它们的update方法来更新自身状态。

6. 总结

综上,观察者模式是软件设计模式中的一种,在此种模式中,一个目标对象管理所有依赖于其的观察者对象,并且当自身的状态改变时,会通知观察者对象,使它们能够自动更新

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/IT小白/article/detail/1018747
推荐阅读
相关标签
  

闽ICP备14008679号