文章目录
- 定义
- 结构
- Demo | 代码
- Subject目标类
- Observer抽象观察者
- 观察者1 | CPU监听器
- 观察者2 | 内存监听器
- 客户端 | Client
- 优点
- 适合场景
定义
所谓观察者模式就是你是被观察的那个对象,你爸爸妈妈就是观察者,一天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事件