【设计模式】观察者模式(定义 | 特点 | Demo入门讲解)

文章目录

定义

所谓观察者模式就是你是被观察的那个对象,你爸爸妈妈就是观察者,一天24h盯着你,一旦你不听话,他们要你听话,你的状态发生变化以后,他们接收到你的状态发生了改变。

结构

如下图,服务器就作为被观察者,三个传感器就是观察者。这是一种抽象的表达方式!

  • Subject被观察的目标
  • Observer观察者抽象类
  • 具体观察者实现类
  • Client客户端

Demo | 代码

Subject目标类

我们需要一个Subject目标类,内部含有观察者对象的集合,在必要的时候触发事件。

  • Subject被观察的目标
  • Observer观察者抽象类
  • 具体观察者实现类
  • Client客户端
java 复制代码
/**
 * 这个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抽象观察者

这个抽象主要是封装了目标对象和观察者要做的事情。

java 复制代码
/**
 * @author linghu
 * @date 2024/7/4 12:02
 */
public abstract class Observer {
    protected Server subject;//服务类,目标对象
    public abstract void update();//观察者要做的事情
}

观察者1 | CPU监听器

java 复制代码
/**
 * @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 | 内存监听器

java 复制代码
/**
 * @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

java 复制代码
/**
 * 观察者模式:让多个观察者对象同时监听某一个主题对象。
 * 这个主题对象在状态发生变化时,会通知所有观察者对象,
 * 使它们能够自动更新自己。
 * @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事件
相关推荐
星夜泊客5 小时前
Unity 游戏开发中的防御性编程与空值处理实践
unity·设计模式·游戏引擎
碎像7 小时前
Windows系统暂停强制更新的操作(超详细说明)
windows
Adellle7 小时前
设计模式的介绍
设计模式
达斯维达的大眼睛7 小时前
设计模式-单列模式
设计模式·cpp
Javatutouhouduan8 小时前
记一次redis主从切换导致的数据丢失与陷入只读状态故障
java·redis·设计模式·java面试·高可用·java后端·java程序员
数据知道10 小时前
Go语言设计模式:抽象工厂模式详解
设计模式·golang·抽象工厂模式·go语言
数据知道10 小时前
Go语言设计模式:组合模式详解
设计模式·golang·组合模式·go语言
有意义12 小时前
Spring Boot 项目中部门查询功能实现与依赖注入优化
后端·设计模式
Bruce_Liuxiaowei15 小时前
SMB签名关闭的安全风险探讨
运维·windows·安全·网络安全
岁忧15 小时前
Go channel 的核心概念、操作语义、设计模式和实践要点
网络·设计模式·golang