设计模式——观察者模式

观察者模式(世界线的观测者)

定义

观察者模式(Observer Partern)也叫做发布/订阅模式(Publish/Subscribe),一种以监听为核心的设计模式。

定义对象间一种一对多的依赖关系,使得每当一个对象改变状态,则所有依赖于它的对象都会得到通知并被自动更新。

优缺点、应用场景

优点

  1. 观察者和被观察者之间是抽象耦合。如此不论是增加观察者还是被观察者都非常容易拓展,而且都是Java中已经实现的抽象层级定义。
  2. 建立一套触发机制。蝴蝶效应,一举一动都会影响世界线的变动。

缺点

需要考虑开发和运行效率,一般会采用异步的方式。

应用场景

  1. 关联行为场景。关联行为是可拆分的,而不是耦合的"组合"关系
  2. 事件多级触发场景
  3. 跨系统的消息交换场景,如消息队列的上下游消息的传递。

代码模拟场景

战国时期秦国的丞相李斯想要监控韩非子的一举一动,于是安插间谍在韩非子周围

实验小结

  1. 将观察者嵌入到被观察者类中确实能够实现监控,但是不利于观察者的拓展
  2. 现需要两个接口Observer和Observable
  3. 前者是观察者实现的,需要重写update方法,决定监听到方法执行后的逻辑
  4. 后者是被观察者实现的,将所有参与观察的观察者封装成集合,执行方法时统一通知。
    然后去欺骗世界吧,命运石之门必定存在,EL PSY CONGROO

观察者模式

UML图

观察者接口与实现类

java 复制代码
/**
 * 观察者接口
 */
public interface Observer {
	// 被观察者操作则通知
	public void update(String context);
}

public class LiSi implements Observer {
	// 若韩非子有动向,立即知晓
	@Override
	public void update(String context) {
		System.out.println("李斯:观察到韩非子活动,开始向上级汇报");
		this.reportToEmperor(context);
		System.out.println("李斯:汇报完毕。。\n");
	}

	private void reportToEmperor(String context) {
		System.out.println("李斯:报~~~!韩非子有活动了----->" + context);
	}
}

/**
 * 张苍,同韩非子、李斯为荀子的弟子
 * 助刘邦统一,官至丞相
 */
public class ZhangCang implements Observer {
	@Override
	public void update(String context) {
		System.out.println("张苍:观察到韩非子活动,开始♂摸索");
		jieBroQuotation(context);
		System.out.println("张苍:摸索♂结束");
	}
	public void jieBroQuotation(String context) {
		System.out.println("张苍:韩非子有活动?让我康康!!------->" + context);
	}
}

被观察者接口及实现类

java 复制代码
/**
 * 被观察者接口
 */
public interface Observable {
	// 增加一个观察者
	public void addObserver(Observer observer);
	// 删除一个观察者
	public void deleteObserver(Observer observer);
	// 被观察者操作时,通知观察者
	public void notifyObservers(String context);
}

被观察者个性接口

java 复制代码
/**
 * 被观察者接口
 */
public interface IHanFeiZi {
	// 韩非子吃早餐
	public void haveBreakfast();
	// 韩非子玩♂游♂戏
	public void haveFun();
}

public class HanFeiZi implements Observable,IHanFeiZi {
	// 所有的观察者放在一个集合中
	private List<Observer> observerList = new ArrayList<>();

	// 韩非子要吃饭了
	@Override
	public void haveBreakfast() {
		System.out.println("韩非子:开始吃饭了。。。");
		this.notifyObservers("韩非子在吃饭");
	}
	// 韩非子要玩♂游♂戏了
	@Override
	public void haveFun() {
		System.out.println("韩非子:玩♂游♂戏");
		this.notifyObservers("韩非子在玩♂游♂戏");
	}
	// 添加一个观察者
	@Override
	public void addObserver(Observer observer) {
		this.observerList.add(observer);
	}
	// 删除一个观察者
	@Override
	public void deleteObserver(Observer observer) {
		this.observerList.remove(observer);
	}
	// 通知观察者们
	@Override
	public void notifyObservers(String context) {
		for (Observer observer : observerList) {
			observer.update(context);
		}
	}
}

入口类方法

java 复制代码
public static void realObserve() {
	// 观察者阵容
	Observer liSi = new LiSi();
	Observer zhangCang = new ZhangCang();
	// 被观察者
	HanFeiZi hanFeiZi = new HanFeiZi();
	hanFeiZi.addObserver(liSi);
	hanFeiZi.addObserver(zhangCang);
	// 被观察者开始动作
	hanFeiZi.haveBreakfast();
	hanFeiZi.haveFun();
}

结果

参考书籍

秦小波《设计模式之禅》

相关推荐
七月丶2 天前
别再手动凑 PR 了:这个 AI Skill 会按仓库习惯自动建分支、拆提交、提 PR
人工智能·设计模式·程序员
刀法如飞2 天前
从程序员到架构师:6大编程范式全解析与实践对比
设计模式·系统架构·编程范式
九狼2 天前
Flutter + Riverpod +MVI 架构下的现代状态管理
设计模式
静水流深_沧海一粟2 天前
04 | 别再写几十个参数的构造函数了——建造者模式
设计模式
StarkCoder2 天前
从UIKit到SwiftUI的迁移感悟:数据驱动的革命
设计模式
阿星AI工作室3 天前
给openclaw龙虾造了间像素办公室!实时看它写代码、摸鱼、修bug、写日报,太可爱了吧!
前端·人工智能·设计模式
_哆啦A梦4 天前
Vibe Coding 全栈专业名词清单|设计模式·基础篇(创建型+结构型核心名词)
前端·设计模式·vibecoding
阿闽ooo7 天前
中介者模式打造多人聊天室系统
c++·设计模式·中介者模式
小米4967 天前
js设计模式 --- 工厂模式
设计模式