设计模式 - Observer Pattern 观察者模式

文章目录

定义

观察者模式是行为型模式的一种,它定义对象间的一种一对多的依赖关系,使得每当一个对象改变状态,它的所有依赖都会收到通知并且自动更新状态。

简单来说就是:当一个行为发生时传递信息给另外一个用户接收做出相应的处理,它们之间其实没有什么直接的关联。

观察者模式的实现构成

构成

  1. 主题(Subject) :抽象主题,提供方法来增加和删除观察者,当自身状态发生改变时,通知所有观察者。

  2. 观察者(Observer) :抽象观察者,用于接收主题状态更新的通知。

  3. 具体主题(Concrete Subject) :实现主题接口、在其内部状态发生改变时,通知所有注册的观察者。

  4. 具体观察者(Concrete Observer):实现观察者接口、在接收到主题的通知时更新自身状态。

UML图

观察者模式的代码实现

场景

假设我们有一个股票价格监控系统,不同的模块(图表模块、统计模块和警报模块),它们需要实时更新股票价格信息。当股票价格发生变化时,这些模块就立即可以获取到通知并且可以进行更新显示。

代码实现

观察者接口

java 复制代码
// 观察者接口,定义更新方法
interface Observer {
	// 当主题状态变化时调用此方法通知观察者。
    void update(double price);
}

具体观察者

java 复制代码
// 具体观察者:图表模块
class ChartDisplay implements Observer {
    @Override
    public void update(double price) {
        System.out.println("图表模块更新股票价格: " + price);
    }
}

// 具体观察者:统计模块
class StatisticsDisplay implements Observer {
    @Override
    public void update(double price) {
        System.out.println("统计模块更新股票价格: " + price);
    }
}

// 具体观察者:警报模块
class AlertSystem implements Observer {
    @Override
    public void update(double price) {
        if (price > 100.0) {
            System.out.println("警报!股票价格超过100元: " + price);
        }
    }
}

主题接口

java 复制代码
// 主题接口,定义增加、删除观察者及通知方法,用于管理和通知观察者。
interface Subject {
    void addObserver(Observer observer);
    void removeObserver(Observer observer);
    void notifyObservers();
}

具体主题

java 复制代码
// 具体主题:实现了Subject,用来维护观察者列表并在价格变化时通知所有观察者。
class StockPrice implements Subject {
    private List<Observer> observers;
    private double price;

    public StockPrice() {
        observers = new ArrayList<>();
    }

    @Override
    public void addObserver(Observer observer) {
        observers.add(observer);
    }

    @Override
    public void removeObserver(Observer observer) {
        observers.remove(observer);
    }

    @Override
    public void notifyObservers() {
        for (Observer observer : observers) {
            observer.update(price);
        }
    }

    // 设置新价格并通知观察者
    public void setPrice(double price) {
        this.price = price;
        notifyObservers();
    }
}

客户端代码

java 复制代码
// 客户端代码
public class ObserverPatternDemo {
    public static void main(String[] args) {
        // 创建具体主题
        StockPrice stockPrice = new StockPrice();

        // 创建具体观察者
        ChartDisplay chartDisplay = new ChartDisplay();
        StatisticsDisplay statisticsDisplay = new StatisticsDisplay();
        AlertSystem alertSystem = new AlertSystem();

        // 注册观察者
        stockPrice.addObserver(chartDisplay);
        stockPrice.addObserver(statisticsDisplay);
        stockPrice.addObserver(alertSystem);

        // 更新股票价格
        stockPrice.setPrice(95.0);
        System.out.println();

        stockPrice.setPrice(105.0);
    }
}

总结

优点

  1. 解耦:主题只需知道观察者实现了某个接口,不需要知道具体实现细节,双方可以独立变化。

  2. 目标与观察者之间建立了一套触发机制。

缺点

  1. 当观察者对象很多时,通知的发布会花费很长时间,影响程序的效率。

  2. 如果在观察者和观察目标之间有循环依赖的话,观察目标会触发它们之间进行循环调用,可能导致系统崩溃。

应用场景

跨系统的消息交换场景,如消息队列,事件总线的处理机制

其他设计模式文章:

相关推荐
寻星探路2 分钟前
【深度长文】深入理解网络原理:TCP/IP 协议栈核心实战与性能调优
java·网络·人工智能·python·网络协议·tcp/ip·ai
AI_56785 分钟前
基于职业发展的Python与Java深度对比分析
java·人工智能·python·信息可视化
Elieal6 分钟前
EasyExcel 实现 Excel 导入导出
java·excel
程序猿20238 分钟前
MySQL的逻辑存储结构
java·数据库·mysql
寻星探路12 分钟前
【Python 全栈测开之路】Python 进阶:库的使用与第三方生态(标准库+Pip+实战)
java·开发语言·c++·python·ai·c#·pip
会员果汁2 小时前
13.设计模式-适配器模式
设计模式·适配器模式
海边的Kurisu3 小时前
苍穹外卖日记 | Day1 苍穹外卖概述、开发环境搭建、接口文档
java
C雨后彩虹7 小时前
任务最优调度
java·数据结构·算法·华为·面试
heartbeat..7 小时前
Spring AOP 全面详解(通俗易懂 + 核心知识点 + 完整案例)
java·数据库·spring·aop
Jing_jing_X7 小时前
AI分析不同阶层思维 二:Spring 的事务在什么情况下会失效?
java·spring·架构·提升·薪资