设计模式系列----观察者模式理解
观察者模式的特点: 被观察者 和观察者 一般是 一对多的关系,一个被观察者
对应多个观察者,当一个被观察者的状态发生改变时,被观察者通知观察者, 然后可以在观察者内部 进行业务逻辑的处理。
观察者模式的使用场景:
1、当面试时,如果面试官问到了消息队列的面试题,让你写一个发布订阅模式的代码,这时就可以借鉴观察者模式的代码了(真的会被这样问)。
2、消息队列在哪里能用,观察者模式就能在哪里用
很多人会混淆观察者模式和发布订阅模式。
观察者模式本质上和发布订阅模式是一样的。
观察者模式是:被观察者拥有所有观察者的注册信息,主动将消息发给所有观察者。
发布订阅模式是在被观察者和观察者之间增加了一个broker(中间人)的角色,使得被观察者和观察者之间可以互不相识,由broker进行转发给指定的观察者们。
仔细想想,中间人和观察者之间的关系不就是类似于被观察者和观察者之间的关系嘛。
所以所两者是没有本质区别的,不过发布订阅模式可以处理更加复杂的逻辑,在分布式系统中,使用发布订阅模式是更加合适的。比如各种消息队列,使用的就是发布订阅模式。
观察者模式在代码层面上,是有四个角色的,包括抽象被观察者(抽象主题),具体被观察者(具体主题),抽象观察者,具体观察者。具体角色继承抽象角色进行统一行为。
先定义一个抽象观察者
public abstract class Observer {
/**
* 具体被观察则通过此方法通知具体观察者
*/
public abstract void update();
}
定义两个具体观察者
public class ConcreteObserver extends Observer {
@Override
public void update() {
System.out.println("观察者1接收到通知");
}
}
public class ConcreteObserver2 extends Observer {
@Override
public void update() {
System.out.println("观察者2接收到通知");
}
}
定义抽象被观察者(抽象主题)
public abstract class Subject {
/**
* 观察者们的注册信息
*/
protected List<Observer> observers = new ArrayList<>();
/**
* 增加观察者
*/
public void attach(Observer observer)
{
observers.add(observer);
}
/**
* 移除观察者
*/
public void remove(Observer observer)
{
observers.remove(observer);
}
/**
* 通知观察者
*/
public abstract void inform ();
}
定义具体被观察者(具体主题)
public class ConcreteSubject extends Subject {
@Override
public void inform() {
observers.forEach(Observer::update);
}
}
定义调用方法
public class Test2 {
public static void main(String[] args) {
Subject concreteSubject = new ConcreteSubject();
//观察者在被观察中注册
ConcreteObserver concreteObserver = new ConcreteObserver();
ConcreteObserver2 concreteObserver2 = new ConcreteObserver2();
concreteSubject.attach(concreteObserver);
concreteSubject.attach(concreteObserver2);
//通知观察者们
concreteSubject.inform();
}
}
结果
在实际场景中,举个例子,用户下单了,那么商品库存要改,订单表要增加记录,用户的购物积分也要加,等等,下单操作就是被观察者,商品库存,订单表,购物积分就是观察者。
–我是“道祖且长”,一个在互联网"苟且偷生"的Java程序员
“有任何问题,可评论,我看到就会回复”
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· AI 智能体引爆开源社区「GitHub 热点速览」
· 从HTTP原因短语缺失研究HTTP/2和HTTP/3的设计差异
· 三行代码完成国际化适配,妙~啊~