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

简介: 设计模式-行为型模式:观察者模式

1、简介

观察者模式是一种软件设计模式,它定义了一种一对多的依赖关系,让多个观察者对象同时监听一个主题对象,当主题对象发生变化时,所有的观察者对象都会得到通知并且自动更新。

2、组成部分

观察者模式中的三个核心角色包括:

  1. 主题(Subject):被观察的对象,通常会维护一个观察者列表,以便在状态发生变化时通知观察者。
  2. 观察者(Observer):观察主题对象的状态变化,当主题状态发生变化时,观察者将得到通知并执行相应的操作。
  3. 具体主题(ConcreteSubject):具体的主题实现类,负责维护一个观察者列表,并实现主题对象状态变化的通知逻辑。
  4. 具体观察者(ConcreteObserver):具体的观察者实现类,实现观察者接口,并定义观察者接收到通知后的具体操作。

3、优缺点

观察者模式的优点包括:

  1. 降低对象之间的耦合性:主题对象和观察者对象之间的关系是松散的,它们之间并没有直接依赖关系,使得它们之间的交互变得灵活和可扩展。
  2. 符合“开闭原则”:当需要增加新的观察者对象时,不需要修改主题对象的代码,只需要增加一个新的具体观察者即可。
  3. 支持广播通信:主题对象可以同时通知多个观察者对象,使得多个观察者对象可以同时对主题对象的状态变化进行响应。

观察者模式的缺点包括:

  1. 观察者数量过多会导致性能问题:如果观察者数量过多,每次状态变化都需要通知所有的观察者对象,会导致性能问题。
  2. 观察者与主题的依赖关系可能会导致循环引用:观察者对象和主题对象之间是相互依赖的,如果设计不当可能会导致循环引用问题。
  3. 可能会出现状态不一致问题:如果观察者对象在收到通知后执行的操作与主题对象的状态更新操作不同步,可能会导致观察者对象的状态与主题对象的状态不一致。
  4. 观察者对象接收到的通知是有序的:通知的顺序可能会影响观察者对象的执行结果,如果观察者对象之间有相互依赖关系,可能会影响整个系统的正确性。
  5. 观察者模式可能会导致性能问题题:如果主题对象在通知观察者对象时,需要执行较为复杂的操作,可能会影响整个系统的性能。

总体来说,观察者模式是一种很有用的设计模式,它可以实现对象之间的松耦合,提高代码的可维护性和可扩展性。但是在使用时需要注意上述缺点,并结合具体的业务场景进行选择。

4、使用场景

观察者模式的使用场景包括:

  1. 一个对象的状态变化会影响其他对象:当一个对象的状态发生变化时,其他多个对象需要做出相应的响应,此时可以使用观察者模式。
  2. 对象的状态更新频繁且多个对象需要及时更新:如果一个对象的状态更新非常频繁,多个对象需要及时更新状态,那么使用观察者模式可以提高程序的效率。
  3. 对象需要在不同的情况下通知不同的观察者对象:当对象需要在不同的情况下通知不同的观察者对象时,可以使用观察者模式。这种情况下,每个观察者对象只需要关注它所感兴趣的通知即可。
  4. 想要实现事件监听器:当需要在程序中实现事件监听器时,可以使用观察者模式。例如,在Java中,可以使用Swing框架中的观察者模式来实现图形界面组件的事件监听器。
  5. MVC模式中的视图与模型:在MVC(Model-View-Controller)模式中,视图层需要对模型层进行监听,当模型层发生变化时,视图层需要及时更新自己的显示。此时可以使用观察者模式,将视图层作为观察者对象,将模型层作为主题对象。

总之,当需要在多个对象之间实现松耦合的消息传递时,可以考虑使用观察者模式。观察者模式适用于需要动态更新的场景,可以帮助我们将代码设计得更加灵活和可扩展。

5、代码实现

下面是一个使用Java实现观察者模式的示例,并对代码进行详细说明:

1、首先定义主题接口Subject和观察者接口Observer:

1. public interface Subject {
2. void registerObserver(Observer observer);
3. void removeObserver(Observer observer);
4. void notifyObservers();
5. }
1. public interface Observer {
2. void update(float temperature, float humidity, float pressure);
3. }

2、定义具体的主题类WeatherData,实现Subject接口:

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

3、定义具体的观察者类CurrentConditionsDisplay,实现Observer接口:

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

4、编写测试代码:

1. public class WeatherStation {
2. public static void main(String[] args) {
3. WeatherData weatherData = new WeatherData();
4. 
5. CurrentConditionsDisplay currentDisplay = new CurrentConditionsDisplay(weatherData);
6. 
7.         weatherData.setMeasurements(80, 65, 30.4f);
8.         weatherData.setMeasurements(82, 70, 29.2f);
9.         weatherData.setMeasurements(78, 90, 29.2f);
10.     }
11. }

运行以上代码,输出结果如下:

       Current conditions: 80.0F degrees and 65.0% humidity

       Current conditions: 82.0F degrees and 70.0% humidity

       Current conditions: 78.0F degrees and 90.0% humidity

以上代码演示了观察者模式的基本实现,具体说明如下:

  • WeatherData类是主题类,它维护了一个观察者列表,实现了Subject接口中的三个方法:registerObserver、removeObserver和notifyObservers,用来注册观察者、移除观察者和通知观察者。WeatherData类还定义了一个measurementsChanged方法,用来在气象数据发生变化时通知观察者。
  • CurrentConditionsDisplay类是观察者类,它实现了Observer接口中的update方法,用来更新观测值,并调用display方法展示当前观测值。CurrentConditionsDisplay类还在构造方法中注册到主题类中,以便接收气象数据的变化通知。
  • WeatherStation类是测试类,创建了WeatherData和CurrentConditionsDisplay对象,并通过调用setMeasurements方法模拟气象数据的变化,然后观察当前观测值是否会被更新和显示出来。

观察者模式的实现可以让主题类和观察者类分离,使它们之间的依赖性降到最低,提高了代码的灵活性和可扩展性。当主题对象发生变化时,所有注册的观察者对象都会收到通知,可以进行相应的处理,实现了松耦合。

需要注意的是,观察者模式也存在一些缺点。当观察者对象较多时,主题对象的通知会导致较大的开销;观察者对象需要实现update方法,这可能会导致代码的复杂性增加。因此,在使用观察者模式时需要根据具体情况进行权衡和选择。

相关文章
|
4月前
|
设计模式 缓存 Java
Java设计模式(二):观察者模式与装饰器模式
本文深入讲解观察者模式与装饰器模式的核心概念及实现方式,涵盖从基础理论到实战应用的全面内容。观察者模式实现对象间松耦合通信,适用于事件通知机制;装饰器模式通过组合方式动态扩展对象功能,避免子类爆炸。文章通过Java示例展示两者在GUI、IO流、Web中间件等场景的应用,并提供常见陷阱与面试高频问题解析,助你写出灵活、可维护的代码。
|
2月前
|
设计模式 消息中间件 传感器
Java 设计模式之观察者模式:构建松耦合的事件响应系统
观察者模式是Java中常用的行为型设计模式,用于构建松耦合的事件响应系统。当一个对象状态改变时,所有依赖它的观察者将自动收到通知并更新。该模式通过抽象耦合实现发布-订阅机制,广泛应用于GUI事件处理、消息通知、数据监控等场景,具有良好的可扩展性和维护性。
321 8
|
7月前
|
设计模式 网络协议 Java
【设计模式】【行为型模式】状态模式(State)
一、入门 什么是状态模式? 状态模式(State Pattern)是一种行为设计模式,允许对象在其内部状态改变时改变其行为,使其看起来像是改变了类。状态模式的核心思想是将对象的状态封装成独立的类,并将
329 16
|
7月前
|
设计模式 算法 前端开发
【设计模式】【行为型模式】职责链模式(Chain of Responsibility)
一、入门 什么是职责链模式? 职责链模式是一种行为设计模式,它允许你将请求沿着一条链传递,直到有对象处理它为止。每个对象都有机会处理请求,或者将其传递给链中的下一个对象。 为什么需要职责链模式? 使用
316 16
|
7月前
|
设计模式 存储 Java
【设计模式】【行为型模式】备忘录模式(Memento)
一、入门 什么是备忘录模式? 备忘录模式(Memento Pattern)是一种行为设计模式,用于在不破坏封装性的前提下,捕获并外部化一个对象的内部状态,以便在需要时恢复该状态。它通常用于实现撤销操作
262 8
|
7月前
|
设计模式 消息中间件 Java
【设计模式】【行为型模式】命令模式(Command)
一、入门 什么是命令模式? 命令模式是一种行为设计模式,它将请求或操作封装为对象,从而使你可以用不同的请求对客户进行参数化,并支持请求的排队、记录、撤销等操作。 命令模式的核心是将“请求”封装为独立的
246 15
|
7月前
|
设计模式 算法 搜索推荐
【设计模式】【行为型模式】策略模式(Strategy)
一、入门 什么是策略模式? 策略模式是一种行为设计模式,允许在运行时选择算法或行为。它将算法封装在独立的类中,使得它们可以互换,而不影响客户端代码。 为什么需要策略模式? 策略模式的主要目的是解决算法
152 14
|
7月前
|
设计模式 数据采集 算法
【设计模式】【行为型模式】模板方法模式(Template Method)
一、入门 1.1、什么是模板方法模式? 模板模式(Template Method Pattern)是一种行为设计模式,它定义了一个算法的框架,并允许子类在不改变算法结构的情况下重新定义算法的某些步骤。
263 13
|
7月前
|
设计模式 Java 编译器
【设计模式】【行为型模式】解释器模式(Interpreter)
一、入门 什么是解释器模式? 解释器模式(Interpreter Pattern)是一种行为设计模式,用于定义语言的语法表示,并提供一个解释器来处理该语法。它通常用于需要解释和执行特定语言或表达式的场
202 11
|
7月前
|
设计模式 存储 JavaScript
【设计模式】【行为型模式】迭代器模式(Iterator)
一、入门 什么是迭代器模式? 迭代器模式(Iterator Pattern)是一种行为设计模式,它提供了一种顺序访问聚合对象中元素的方法,而不需要暴露其底层表示。迭代器模式将遍历逻辑从聚合对象中分离出
217 11

热门文章

最新文章