当前位置: 首页 > news >正文

设计模式——观察者模式(Observer Pattern)+ Spring相关源码

文章目录

  • 一、观察者模式定义
  • 二、例子
    • 2.1 菜鸟教程例子
      • 2.1.1 定义观察者
      • 2.1.2 定义被观察对象
      • 2.1.3 使用
    • 2.2 JDK源码 —— Observable
      • 2.2.1 观察者接口Observer
      • 2.2.1 被观察者对象Observable
    • 2.3 Spring源码 —— AbstractApplicationContext
      • 2.3.1 观察者
      • 2.3.2 被观察者
    • 2.3 Guava源码 —— EventBus
  • 三、其他设计模式


一、观察者模式定义

类型:行为型模式
目的:当一个对象的状态发生改变时,其所有依赖者(观察者)都会收到通知并自动更新。


二、例子

2.1 菜鸟教程例子

2.1.1 定义观察者

//观察者
public abstract class Observer {//被观察对象protected Subject subject;public abstract void update();
}
public class BinaryObserver extends Observer{public BinaryObserver(Subject subject){this.subject = subject;this.subject.attach(this);}@Overridepublic void update() {System.out.println( "Binary String: " + Integer.toBinaryString( subject.getState() ) ); }
}
public class HexaObserver extends Observer{public HexaObserver(Subject subject){this.subject = subject;this.subject.attach(this);}@Overridepublic void update() {System.out.println( "Hex String: "  + Integer.toHexString( subject.getState() ).toUpperCase() ); }
}

2.1.2 定义被观察对象

import java.util.ArrayList;
import java.util.List;
//被观察对象 
public class Subject {//观察者列表private List<Observer> observers = new ArrayList<Observer>();private int state;public int getState() {return state;}public void attach(Observer observer){observers.add(observer);      }//通知所有观察者public void notifyAllObservers(){for (Observer observer : observers) {observer.update();}}  //修改数据时,通知所有观察者public void setState(int state) {this.state = state;notifyAllObservers();}
}

2.1.3 使用

public class ObserverPatternDemo {public static void main(String[] args) {//创建被观察对象Subject subject = new Subject();//创建观察者对象new HexaObserver(subject);new BinaryObserver(subject);//创建被观察对象调用setState时,通知国有观察者System.out.println("First state change: 15");   subject.setState(15);System.out.println("Second state change: 10");  subject.setState(10);}
}

2.2 JDK源码 —— Observable

2.2.1 观察者接口Observer

public interface Observer {void update(Observable o, Object arg);
}

2.2.1 被观察者对象Observable

public class Observable {private boolean changed = false;private Vector<Observer> obs;//添加观察者public synchronized void addObserver(Observer o) {if (o == null)throw new NullPointerException();if (!obs.contains(o)) {obs.addElement(o);}}//通知观察者public void notifyObservers(Object arg) {Object[] arrLocal;synchronized (this) {if (!changed)return;arrLocal = obs.toArray();clearChanged();}for (int i = arrLocal.length-1; i>=0; i--)((Observer)arrLocal[i]).update(this, arg);}
}

2.3 Spring源码 —— AbstractApplicationContext

2.3.1 观察者

public class ContextStartedEvent extends ApplicationContextEvent {public ContextStartedEvent(ApplicationContext source) {super(source);}
}
public class ContextStoppedEvent extends ApplicationContextEvent {public ContextStoppedEvent(ApplicationContext source) {super(source);}
}
public class ContextRefreshedEvent extends ApplicationContextEvent {public ContextRefreshedEvent(ApplicationContext source) {super(source);}
}

2.3.2 被观察者

public abstract class AbstractApplicationContext extends DefaultResourceLoader implements ConfigurableApplicationContext {//观察者集合private Set<ApplicationEvent> earlyApplicationEvents;//添加观察者Eventpublic void publishEvent(ApplicationEvent event) {this.publishEvent(event, (ResolvableType)null);}//通知观察者Eventprotected void registerListeners() {Iterator var1 = this.getApplicationListeners().iterator();while(var1.hasNext()) {ApplicationListener<?> listener = (ApplicationListener)var1.next();this.getApplicationEventMulticaster().addApplicationListener(listener);}String[] listenerBeanNames = this.getBeanNamesForType(ApplicationListener.class, true, false);String[] var7 = listenerBeanNames;int var3 = listenerBeanNames.length;for(int var4 = 0; var4 < var3; ++var4) {String listenerBeanName = var7[var4];this.getApplicationEventMulticaster().addApplicationListenerBean(listenerBeanName);}Set<ApplicationEvent> earlyEventsToProcess = this.earlyApplicationEvents;this.earlyApplicationEvents = null;if (!CollectionUtils.isEmpty(earlyEventsToProcess)) {Iterator var9 = earlyEventsToProcess.iterator();while(var9.hasNext()) {ApplicationEvent earlyEvent = (ApplicationEvent)var9.next();this.getApplicationEventMulticaster().multicastEvent(earlyEvent);}}}
}

2.3 Guava源码 —— EventBus

public class EventBus {//注册订阅者(观察者)public void register(Object object) {this.subscribers.register(object);}//通知订阅者(观察者)public void post(Object event) {Iterator<Subscriber> eventSubscribers = this.subscribers.getSubscribers(event);if (eventSubscribers.hasNext()) {this.dispatcher.dispatch(event, eventSubscribers);} else if (!(event instanceof DeadEvent)) {this.post(new DeadEvent(this, event));}}
}

三、其他设计模式

创建型模式
结构型模式

  • 1、设计模式——装饰器模式(Decorator Pattern)+ Spring相关源码

行为型模式

  • 1、设计模式——访问者模式(Visitor Pattern)+ Spring相关源码
  • 2、设计模式——中介者模式(Mediator Pattern)+ JDK相关源码
  • 3、设计模式——策略模式(Strategy Pattern)+ Spring相关源码
  • 4、设计模式——状态模式(State Pattern)
  • 5、设计模式——观察者模式(Observer Pattern)+ Spring相关源码

相关文章:

  • 汽车托运如何确保安全
  • 企业工程项目管理系统源码(三控:进度组织、质量安全、预算资金成本、二平台:招采、设计管理)
  • 【蓝桥杯 第十四届省赛Java B组】真题训练(A - C)正在更新
  • 什么是神经网络,它的原理是啥?(1)
  • C++二分查找算法的应用:俄罗斯套娃信封问题
  • 开发环境配置之Linux安装golang
  • 【vscode】Window11环境下vscode使用Fira Code字体【教程】
  • 【快刊推荐】EI快刊盘点,仅29天录用,国人友好,接收领域广!
  • Qt 6 MinGW使用GSL库的方法
  • win10 + vs2017 + cmake3.17 编译 curl-7.48
  • 使用 OpenSSL 工具撰写 Bash 脚本进行密码明文的加密与解密
  • 用Go实现两个线程交替打印奇数和偶数
  • VS Code开发Java之快速入门
  • AI智能语音识别模块(二)——基于Arduino的语音控制MP3播放器
  • Go 多版本管理
  • Cumulo 的 ClojureScript 模块已经成型
  • Docker容器管理
  • JavaScript设计模式系列一:工厂模式
  • Js基础——数据类型之Null和Undefined
  • OpenStack安装流程(juno版)- 添加网络服务(neutron)- controller节点
  • REST架构的思考
  • vue2.0一起在懵逼的海洋里越陷越深(四)
  • 技术发展面试
  • 系统认识JavaScript正则表达式
  • 用Visual Studio开发以太坊智能合约
  • 白色的风信子
  • ​【原创】基于SSM的酒店预约管理系统(酒店管理系统毕业设计)
  • ​io --- 处理流的核心工具​
  • ​ssh-keyscan命令--Linux命令应用大词典729个命令解读
  • ​软考-高级-系统架构设计师教程(清华第2版)【第15章 面向服务架构设计理论与实践(P527~554)-思维导图】​
  • !!【OpenCV学习】计算两幅图像的重叠区域
  • #laravel 通过手动安装依赖PHPExcel#
  • $.proxy和$.extend
  • (poj1.3.2)1791(构造法模拟)
  • (Redis使用系列) Springboot 实现Redis消息的订阅与分布 四
  • (编程语言界的丐帮 C#).NET MD5 HASH 哈希 加密 与JAVA 互通
  • (附源码)spring boot建达集团公司平台 毕业设计 141538
  • (十) 初识 Docker file
  • (算法)前K大的和
  • (转)Mysql的优化设置
  • (转)大型网站的系统架构
  • .NET Core 和 .NET Framework 中的 MEF2
  • .NET Micro Framework初体验(二)
  • @cacheable 是否缓存成功_让我们来学习学习SpringCache分布式缓存,为什么用?
  • @FeignClient 调用另一个服务的test环境,实际上却调用了另一个环境testone的接口,这其中牵扯到k8s容器外容器内的问题,注册到eureka上的是容器外的旧版本...
  • [Android]使用Android打包Unity工程
  • [ASP.NET MVC]如何定制Numeric属性/字段验证消息
  • [bzoj1912]异象石(set)
  • [C#] 基于 yield 语句的迭代器逻辑懒执行
  • [CareerCup] 14.5 Object Reflection 对象反射
  • [CF543A]/[CF544C]Writing Code
  • [EFI]MSI GF63 Thin 9SCXR电脑 Hackintosh 黑苹果efi引导文件
  • [JavaWeb]—Spring入门
  • [Java基础] Java中List.remove报错UnsupportedOperationException
  • [java面试]宇信易诚 广州分公司 java笔试题目回忆录