java设计模式学习之【观察者模式】

文章目录

引言

想象你在一个在线拍卖会上竞标一件珍贵的艺术品。每当有人出价更高,系统都会立即通知你。这个实时更新机制使你可以做出快速反应。这种模式,在软件开发中称为观察者模式,是一种广泛应用于实现事件驱动系统的设计模式。

观察者模式简介

定义与用途

观察者模式(Observer Pattern)是一种行为型设计模式,它定义了对象间的一种一对多的依赖关系,使得每当一个对象改变状态时,其所有依赖者都会得到通知并自动更新。这种模式用于构建松散耦合的系统,其中一个对象的改变可以影响一个或多个其他对象,而无需对象之间有紧密的关联。

实现方式

实现观察者模式通常涉及以下几个关键组件:

  • 主题(Subject):持有观察者的列表,并提供添加、删除观察者的接口。
  • 观察者(Observer):为那些在主题状态发生变化时需获得通知的对象定义一个更新接口。
  • 具体主题(Concrete Subject):状态发生改变时,向所有注册的观察者发出通知。
  • 具体观察者(Concrete Observer):实现观察者接口的类,定义当接收到主题通知时如何更新自己。

使用场景

观察者模式适用于以下场景:

  • 当一个对象的改变需要同时改变其他对象,而不知道具体有多少对象待改变时。
  • 当一个对象必须通知其他对象,而它又不能假定其他对象是谁。

例如:

  • 股票市场应用:股票价格更新时,所有关注该股票的投资者都会收到通知。
  • 社交媒体订阅:用户在社交媒体上订阅某个名人或主题,当有更新时用户可以立即收到通知。
  • 电子邮件系统:当新邮件到达时,电子邮件客户端会通知用户。

优势与劣势

  • 优势
    • 支持简单的广播通信,解除对象间的紧密耦合。
    • 支持实时通知,对象状态改变时,观察者立即得到更新。
  • 劣势
    • 如果观察者非常多,通知会花费较多时间。
    • 如果观察者和主题之间有循环依赖,可能导致系统崩溃。

在Spring框架中的应用

Spring框架广泛应用了观察者模式,尤其是在事件驱动模型中。以下是一些具体应用:

复制代码
1. 事件监听
Spring的事件监听机制就是观察者模式的一个例子。当一个事件被触发时,所有监听该事件的监听器都会收到通知。例如,ApplicationContext 发布了各种类型的事件,如 ContextRefreshedEvent,应用中的各个部分可以通过实现 ApplicationListener 来响应这些事件。

2. WebSocket
在Spring中,WebSocket的实现也使用了观察者模式。服务器和客户端之间的通信建立在这种模式上,当一方发送消息时,另一方可以即时接收和响应。

观察者示例

这个示例展示了观察者模式在Java中的实现。观察者模式是一种行为设计模式,它定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新。

步骤 1:创建主题类

java 复制代码
private List<Observer> observers = new ArrayList<Observer>();
   private int state;

   public int getState() {
      return state;
   }

   public void setState(int state) {
      this.state = state;
      notifyAllObservers();
   }

   public void attach(Observer observer){
      observers.add(observer);		
   }

   public void notifyAllObservers(){
      for (Observer observer : observers) {
         observer.update();
      }
   } 	

Subject 是持有观察者列表的类,并提供了方法来添加和删除观察者。当它的状态改变时,它会通知所有观察者。

步骤 2:创建观察者类

java 复制代码
public abstract class Observer {
   protected Subject subject;
   public abstract void update();
}

Observer 是一个抽象类,为所有具体的观察者定义了一个更新接口。每个具体的观察者都需要实现这个接口。

步骤 3:创建具体的观察者类

java 复制代码
public class BinaryObserver extends Observer{

   public BinaryObserver(Subject subject){
      this.subject = subject;
      this.subject.attach(this);
   }

   @Override
   public void update() {
      System.out.println( "Binary String: " + Integer.toBinaryString( subject.getState() ) ); 
   }
}

BinaryObserver 是一个具体的观察者,它将主题的状态以二进制形式输出。

java 复制代码
public class OctalObserver extends Observer{

   public OctalObserver(Subject subject){
      this.subject = subject;
      this.subject.attach(this);
   }

   @Override
   public void update() {
     System.out.println( "Octal String: " + Integer.toOctalString( subject.getState() ) ); 
   }
}

OctalObserver 是另一个具体的观察者,它将主题的状态以八进制形式输出。

java 复制代码
public class HexaObserver extends Observer{

   public HexaObserver(Subject subject){
      this.subject = subject;
      this.subject.attach(this);
   }

   @Override
   public void update() {
      System.out.println( "Hex String: " + Integer.toHexString( subject.getState() ).toUpperCase() ); 
   }
}

HexaObserver 是第三个具体的观察者,它将主题的状态以十六进制形式输出。

步骤 4:使用主题和具体的观察者对象

java 复制代码
public class ObserverPatternDemo {
   public static void main(String[] args) {
      Subject subject = new Subject();

      new HexaObserver(subject);
      new OctalObserver(subject);
      new BinaryObserver(subject);

      System.out.println("第一次状态改变: 15");	
      subject.setState(15);
      System.out.println("第二次状态改变: 10");	
      subject.setState(10);
   }
}

在这个演示类中,我们创建了一个主题对象和三个观察者对象。然后我们改变了主题的状态,观察者会自动更新并打印出新的状态。

这个示例演示了观察者模式如何在软件设计中用于创建灵活的通知机制,当对象状态改变时,所有依赖于它的对象都会自动更新。这种模式使得对象之间的通信变得更加简洁和松耦合。

代码地址

23种设计模式相关代码后续会逐步提交到github上,方便学习,欢迎指点:
代码地址

https://github.com/RuofeiSun/lf-23Pattern

相关推荐
带刺的坐椅5 分钟前
Java MCP 的鉴权?好简单的啦
java·鉴权·mcp·solon-ai
Pocker_Spades_A8 分钟前
飞算JavaAI家庭记账系统:从收支记录到财务分析的全流程管理方案
java·开发语言
33255_40857_2805913 分钟前
掌握分页艺术:MyBatis与MyBatis-Plus实战指南(10年Java亲授)
java·mybatis
Ashlee_code29 分钟前
香港券商智能櫃台系統技術解決方案——融合跨境清算與AI風控,助力券商把握滬港雙市爆發機遇**
java·科技·金融·重构·架构·系统架构·php
蚰蜒螟40 分钟前
Spring 和 Lettuce 源码分析 Redis 节点状态检查与失败重连的工作原理
java·redis·spring
小张快跑。44 分钟前
Tomcat下载、安装及配置详细教程
java·服务器·tomcat
神仙别闹1 小时前
基于 JSP+Mysql实现MVC房屋租赁系统
java·mysql·mvc
m0_521329031 小时前
java-单元测试
java
掉鱼的猫1 小时前
Java MCP 的鉴权?好简单的啦
java·mcp
Java水解1 小时前
Java最新面试题(全网最全、最细、附答案)
java·后端·面试