当前位置:   article > 正文

设计模式行为型——观察者模式

设计模式行为型——观察者模式

目录

观察者模式的定义

观察者模式的实现

观察者模式角色

观察者模式类图

观察者模式代码实现

观察者模式的特点

优点

缺点

使用场景

注意事项

实际应用


观察者模式的定义

        观察者模式(Observer Pattern)是一种行为型设计模式,它定义了一种一对多的依赖关系,使得当一个对象的状态发生改变时,所有依赖于它的对象都会自动收到通知并更新。观察者模式的别名包括发布-订阅(Publish/Subscribe)模式、模型-视图(Model/View)模式、源-监听器(Source/Listener)模式或从属者(Dependents)模式。

观察者模式的实现

观察者模式角色

  1. 主题角色(Subject):也称为被观察者或可观察者,它是具有状态的对象,并维护着一个观察者列表。主题提供了添加、删除和通知观察者的方法。这个角色可以是接口,也可以是抽象类或者具体的类,因为很多情况下会与其他的模式混用,所以使用抽象类的情况比较多。
  2. 具体主题角色(Concrete Subject):具体主题是主题的具体实现类。它维护着观察者列表,并在状态发生改变时通知观察者。同时它还实现了在目标类中定义的抽象业务逻辑方法(如果有的话)。如果无须扩展目标类,则具体目标类可以省略。
  3. 观察者角色(Observer):观察者是接收主题通知的对象。观察者需要实现一个更新方法,当收到主题的通知时,调用该方法进行更新操作。
  4. 具体观察者角色(Concrete Observer):具体观察者是观察者的具体实现类。它实现了更新方法,定义了在收到主题通知时需要执行的具体操作。存储具体观察者的有关状态,这些状态需要和具体目标的状态保持一致。

观察者模式类图

观察者模式代码实现

主题角色

  1. package com.common.demo.pattern.observer;
  2. import java.util.Vector;
  3. /**
  4. * @author Evan Walker 昂焱数据: https://www.ayshuju.com
  5. * @version 1.0
  6. * @desc 主题角色
  7. * @date 2023/08/07 10:37:05
  8. */
  9. public abstract class Subject {
  10. private Vector<Observer> obs = new Vector();
  11. public void addObserver(Observer obs) {
  12. this.obs.add(obs);
  13. }
  14. public void delObserver(Observer obs) {
  15. this.obs.remove(obs);
  16. }
  17. protected void notifyObserver() {
  18. for (Observer o : obs) {
  19. o.update();
  20. }
  21. }
  22. public abstract void doSomething();
  23. }

具体主题角色

  1. package com.common.demo.pattern.observer;
  2. /**
  3. * @author Evan Walker 昂焱数据: https://www.ayshuju.com
  4. * @version 1.0
  5. * @desc 具体主题角色
  6. * @date 2023/08/07 10:39:23
  7. */
  8. public class ConcreteSubject extends Subject{
  9. @Override
  10. public void doSomething(){
  11. System.out.println("被观察者事件发生改变");
  12. this.notifyObserver();
  13. }
  14. }

观察者角色

  1. package com.common.demo.pattern.observer;
  2. /**
  3. * @author Evan Walker 昂焱数据: https://www.ayshuju.com
  4. * @version 1.0
  5. * @desc 观察者角色 观察者接口
  6. * @date 2023/08/07 10:30:26
  7. */
  8. public interface Observer {
  9. void update();
  10. }

具体观察者角色

  1. package com.common.demo.pattern.observer;
  2. /**
  3. * @author Evan Walker 昂焱数据: https://www.ayshuju.com
  4. * @version 1.0
  5. * @desc 具体观察者角色 观察者角色A
  6. * @date 2023/08/07 10:40:54
  7. */
  8. public class ConcreteObserverA implements Observer{
  9. @Override
  10. public void update() {
  11. System.out.println("观察者A收到信息,并进行业务处理");
  12. }
  13. }
  14. package com.common.demo.pattern.observer;
  15. /**
  16. * @author Evan Walker 昂焱数据: https://www.ayshuju.com
  17. * @version 1.0
  18. * @desc 具体观察者角色 观察者角色B
  19. * @date 2023/08/07 10:40:54
  20. */
  21. public class ConcreteObserverB implements Observer{
  22. @Override
  23. public void update() {
  24. System.out.println("观察者B收到信息,并进行业务处理");
  25. }
  26. }

测试类

  1. package com.common.demo.pattern.observer;
  2. /**
  3. * @author Evan Walker 昂焱数据: https://www.ayshuju.com
  4. * @version 1.0
  5. * @desc 测试类
  6. * @date 2023/08/07 10:46:55
  7. */
  8. public class ClientTest {
  9. public static void main(String[] args) {
  10. Subject sub = new ConcreteSubject();
  11. sub.addObserver(new ConcreteObserverA());
  12. sub.addObserver(new ConcreteObserverB());
  13. sub.doSomething();
  14. }
  15. }

测试截图

观察者模式的特点

优点

  1. 实现了松耦合:观察者模式可以将被观察者和观察者之间的耦合度降低,使得它们可以独立地进行扩展和修改。
  2. 支持广播通信:建立一套广播通信触发机制,被观察者可以同时通知多个观察者,从而支持广播通信的需求。
  3. 符合开闭原则:新增或删除观察者不会影响到被观察者和其他观察者的代码,符合开闭原则的要求。

缺点

  1. 观察者过多可能导致性能问题:如果观察者过多或者观察者的处理逻辑复杂,会影响到系统的性能,花费较多的时间。
  2. 观察者和被观察者直接关联:在一些情况下,观察者和被观察者之间的直接关联可能会导致设计上的困扰。
  3. 观察者和观察目标循环依赖:在观察者和观察目标之间有循环依赖的话,观察目标会触发它们之间进行循环调用,可能导致系统崩溃。 
  4. 观察者对所观察的目标对象黑盒操作:无相应的机制让观察者知道所观察的目标对象是怎么发生变化的,而仅仅只是知道观察目标发生了变化。

使用场景

  1. 当一个对象的改变需要通知其他对象,并且不希望将对象之间的耦合度过高时,可以考虑使用观察者模式。
  2. 当某个对象的状态改变需要引起一系列相关对象的更新时,不需要知道这些对象是谁,不需知道具体有多少对象有待改变,可以使用观察者模式。
  3. 一个抽象模型有两个方面,其中一个方面依赖于另一个方面。将这些方面封装在独立的对象中使它们可以各自独立地改变和复用。

注意事项

  1. 注意观察者和被观察者的关联方式:可以通过接口或抽象类定义观察者接口,使得被观察者只与接口进行交互,而不依赖于具体的观察者实现类。
  2. 避免循环依赖:观察者和被观察者之间应该避免出现循环依赖的情况,否则可能导致无限循环的通知。
  3. 如果顺序执行,某一观察者错误会导致系统卡壳,可采用异步方式进行通知。

实际应用

  1. 网络订阅服务:订阅者可以订阅感兴趣的内容,当内容更新时,订阅者会收到通知。
  2. 消息中间件:多个消息消费者可以同时监听一个消息主题,当主题发布消息时,所有消费者都会接收到通知并处理消息。
  3. GUI界面组件:GUI界面中的事件监听机制就是一种观察者模式的实现。

更多消息资讯,请访问昂焱数据(https://www.ayshuju.com)

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

闽ICP备14008679号