观察者设计模式详解

观察者设计模式详解

文章目录

一、定义

**观察者设计模式(Observer Pattern)**是一种行为设计模式,也叫做 "发布-订阅模式", 它定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象(Subject)。当主题对象的状态发生变化时,所有依赖于它的观察者都会收到通知并自动更新。这个模式常用于实现事件驱动的系统,特别是在 GUI 应用程序、实时更新系统和发布/订阅机制中。

二、观察者模式的结构

  1. Subject(主题/被观察者)
    • 持有观察者的集合。
    • 提供注册、删除观察者的方法。
    • 当状态发生变化时,通知所有注册的观察者。
  2. Observer(观察者)
    • 定义一个更新接口,用于接收通知。
  3. ConcreteSubject(具体主题)
    • 继承自Subject,实现对状态的管理。
    • 当状态改变时,调用notifyObservers()方法通知所有观察者。
  4. ConcreteObserver(具体观察者)
    • 实现Observer接口,在收到通知时更新自身状态。

三、特点

优点

  • 解耦:观察者模式将观察者和主题分离,使得它们之间的依赖关系降到最低。
  • 灵活性:可以动态地增加或减少观察者。
  • 符合开闭原则:扩展观察者或主题的功能,不需要修改已有代码。

缺点

  • 通知成本:如果观察者过多,通知所有观察者可能会造成一定的性能开销。
  • 复杂性:如果观察者和主题之间的依赖关系过于复杂,可能会导致代码难以维护。

四、应用场景

  • 事件监听机制: 当一个对象的状态发生改变时,需要通知多个对象做出相应的响应 ,例如GUI框架中的按钮点击事件监听。
  • 订阅-发布系统: 当很多对象同时对某一个主题感兴趣时,可以采用观察者模式实现发布-订阅模式 ,如消息队列、新闻订阅等。
  • 数据变化通知: 数据库开发中,当数据库表中的数据发生变化时,需要通知相关的模块进行更新或其他操作 , 如MVC架构中的View观察Model的变化。

五、实现

1、uml类图:

2、简单实现代码:

java 复制代码
// 观察者接口
interface Observer {
    void update(String message);
}

// 具体观察者
class ConcreteObserver implements Observer {
    private String name;

    public ConcreteObserver(String name) {
        this.name = name;
    }

    @Override
    public void update(String message) {
        System.out.println(name + " received message: " + message);
    }
}

// 主题接口
interface Subject {
    void attach(Observer observer);
    void detach(Observer observer);
    void notifyObservers();
}

// 具体主题
class ConcreteSubject implements Subject {
    private List<Observer> observers = new ArrayList<>();
    private String state;

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

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

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

    public void setState(String state) {
        this.state = state;
        notifyObservers();
    }
}

// 使用示例
public class ObserverPatternDemo {
    public static void main(String[] args) {
        ConcreteSubject subject = new ConcreteSubject();

        Observer observer1 = new ConcreteObserver("Observer 1");
        Observer observer2 = new ConcreteObserver("Observer 2");

        subject.attach(observer1);
        subject.attach(observer2);

        subject.setState("New State 1");
        subject.setState("New State 2");
    }
}

输出结果:

相关推荐
杨充17 小时前
10.可测试性实战设计
设计模式·开源·代码规范
杨充17 小时前
9.重构十二式的实战
设计模式·开源·代码规范
杨充17 小时前
6.设计原则的全景图
设计模式·开源·全栈
杨充17 小时前
2.面向对象的特性
设计模式
杨充17 小时前
7.SOLID原则案例汇
设计模式·开源·全栈
杨充17 小时前
8.反模式与坏味道
设计模式·开源·代码规范
杨充17 小时前
3.接口vs抽象类比较
设计模式
咖啡八杯20 小时前
文法、BNF与AST
java·设计模式·解释器模式·ast·文法
咖啡八杯1 天前
GoF设计模式——解释器模式
java·后端·spring·设计模式