定义
所谓观察者模式就是你是被观察的那个对象,你爸爸妈妈就是观察者,一天24h盯着你,一旦你不听话,他们要你听话,你的状态发生变化以后,他们接收到你的状态发生了改变。
结构
如下图,服务器就作为被观察者,三个传感器就是观察者。这是一种抽象的表达方式!
- Subject被观察的目标
- Observer观察者抽象类
- 具体观察者实现类
- Client客户端
Demo | 代码
Subject目标类
我们需要一个Subject目标类,内部含有观察者对象的集合,在必要的时候触发事件。
- Subject被观察的目标
- Observer观察者抽象类
- 具体观察者实现类
- Client客户端
/** * 这个Server类就是服务类,作为Subject,别观察的目标! * @author linghu * @date 2024/7/4 11:50 */ public class Server { private List<Observer> observers= new ArrayList<Observer>(); private int cpu; private int memory; public Server() { } //变更服务器状态 public void changeState(int cpu,int memory){ this.cpu=cpu; this.memory=memory; System.out.println("CPU:" + cpu + "%,内存占用:" + memory + "%"); //通知所有观察者对象,使它们能够自动更新自己 notifyAllObservers(); } public Server(int cpu, int memory) { this.cpu = cpu; this.memory = memory; } public int getCpu() { return cpu; } public void setCpu(int cpu) { this.cpu = cpu; } public int getMemory() { return memory; } public void setMemory(int memory) { this.memory = memory; } public void addObserver(Observer observer){ observers.add(observer); } public void notifyAllObservers(){ for (Observer observer :observers) { observer.update(); } } }
Observer抽象观察者
这个抽象主要是封装了目标对象和观察者要做的事情。
/** * @author linghu * @date 2024/7/4 12:02 */ public abstract class Observer { protected Server subject;//服务类,目标对象 public abstract void update();//观察者要做的事情 }
观察者1 | CPU监听器
/** * @author linghu * @date 2024/7/4 12:04 * CPU监听器 */ public class CpuObserver extends Observer{ //传入目标类subject public CpuObserver(Server subject) { //初始化的时候完成数据双向绑定工作 this.subject=subject; this.subject.addObserver(this); } @Override public void update() { //监听CPU的运行状况,负载超过80%就发出警报 if(subject.getCpu() >= 80){ System.out.println("警报:CPU当前" + subject.getCpu()+ "%即将满载,请 速查明原因"); } } }
观察者2 | 内存监听器
/** * @author linghu * @date 2024/7/4 12:46 * 内存监听器 */ public class MemoryObserver extends Observer{ public MemoryObserver(Server subject) { this.subject=subject; this.subject.addObserver(this); } @Override public void update() { if(subject.getMemory() >= 80){ System.out.println("警报:服务器内存已经占用超过" + subject.getMemory()+ "%即将满载,请 速查明原因"); } } }
客户端 | Client
/** * 观察者模式:让多个观察者对象同时监听某一个主题对象。 * 这个主题对象在状态发生变化时,会通知所有观察者对象, * 使它们能够自动更新自己。 * @author linghu * @date 2024/7/4 12:49 * 客户端 */ public class Client { public static void main(String[] args) throws InterruptedException { Server subject = new Server(); //完成两个观察者和一个目标类的绑定 //引入新的观察者,这里可以利用反射,动态加载~ new CpuObserver(subject); new MemoryObserver(subject); //============================== while (true){ int cpu=new Random().nextInt(100); int memory=new Random().nextInt(100); //调用具体的业务~ subject.changeState(cpu,memory); Thread.sleep(5000);//5s } } }
优点
- 开闭原则。 你⽆需修改发布者代码就能引⼊新的订阅者类 (如果是发布者接⼝则可轻松引⼊发布者类)。
- 你可以在运⾏时建⽴对象之间的联系。
适合场景
- 所有的发布订阅模式
- 构建事件监听机制,比如按下触发click事件