十九、观察者模式

  • 目的 : 定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新。
  • 核心 :主题(Subject/Observable)维护观察者列表,提供注册、注销和通知方法。观察者(Observer)实现更新接口。主题状态改变时,调用所有注册观察者的更新方法。
  • 场景 :常用于实现事件处理系统,如GUI组件的事件监听、股票价格变动通知等,当状态改变时自动通知所有订阅者。

首先是观察者接口,定义更新方法

java 复制代码
package observer;

public interface IWatcher {
	void update();
}

与一个具体观察类

java 复制代码
package observer;

public class UpdateWatcher implements IWatcher{

	@Override
	public void update() { // 当被观察对象发生变化时,此方法会被调用
		System.out.println(this + " 观察到目标已经更新了。");
	}
}

然后有一个被观察者接口(也称主题接口 Subject)

java 复制代码
package observer;

public interface IWathedSubject {

	void add(IWatcher watcher); 	// 添加观察者

	void remove(IWatcher watcher);	// 移除观察者

	void update();					// 更新主题状态

	void notifyWatchers();			// 通知所有观察者

}

与具体被观察者类

java 复制代码
package observer;

import java.util.ArrayList;
import java.util.List;

public class UpdateWatchedSubject implements IWathedSubject {
	private List<IWatcher> list;		// 存储观察者列表

	public UpdateWatchedSubject() {
		this.list = new ArrayList<>();	// 初始化观察者列表
	}

	@Override
	public void add(IWatcher watcher) {	// 添加新的观察者
		this.list.add(watcher);	
	}

	@Override
	public void remove(IWatcher watcher) { // 移除指定的观察者
		this.list.remove(watcher);
	}

	@Override
	public void update() {		// 主题状态发生变化时调用
		System.out.println("目标主题状态已更新..."); // 职责分离 状态变更的预处理
		notifyWatchers();						// 纯粹执行观察者通知
	}

	@Override
	public void notifyWatchers() {			// 纯粹执行 通知观察者
		for(IWatcher watcher : list){		// 遍历观察者列表
			watcher.update();				// 调用每个观察者的反应方法
		}
	}
}

最后是函数入口

java 复制代码
package observer;

public class MainTest {
	public static void main(String[] args) {

		//自定义观察者模式
		IWathedSubject watched = new UpdateWatchedSubject();		//创建主题
		watched.add(new UpdateWatcher());							//创建三个观察者
		watched.add(new UpdateWatcher());
		watched.add(new UpdateWatcher());
		watched.update();								//主题状态变化 通知每个观察者
		System.out.println();
	}
}

终端输出

复制代码
目标主题状态已更新...
observer.observer.UpdateWatcher@4aa298b7 观察到目标已经更新了。
observer.observer.UpdateWatcher@7d4991ad 观察到目标已经更新了。
observer.observer.UpdateWatcher@28d93b30 观察到目标已经更新了。
相关推荐
圆山猫6 小时前
[Virtualization](四):Linux KVM/RISC-V 的 vCPU 运行路径
java·linux·risc-v
城管不管6 小时前
ReAct、Plan-and-Execute、Reflection 三大智能 Agent 范式核心区别
java·人工智能·算法·spring·ai·动态规划
IT小白杨7 小时前
从环境制备到自动化工作流:多账号运营的工程化架构拆解
java·经验分享·自动化·安全架构·指纹浏览器
豆瓣鸡7 小时前
算法日记 - Day3
java·开发语言·算法
萧瑟余晖7 小时前
Java深入解析篇九之NIO详解
java·网络·nio
The Chosen One9858 小时前
高进度算法模板速记(待完善)
java·前端·算法
极光代码工作室10 小时前
基于SpringBoot的课程预约系统
java·springboot·web开发·后端开发
Leighteen10 小时前
`try-finally` 里的 `return`:为什么 `finally` 会悄悄改掉返回值、吞掉异常
java·开发语言
名字还没想好☜11 小时前
Go 的 time.After 在 select 循环里内存泄漏:定时器堆积原理与 timer.Reset 正确姿势
java·数据库·golang·go·goroutine
圆山猫11 小时前
[Virtualization](三):RISC-V H-extension 与 Guest 执行模式
android·java·risc-v