温馨提示×

温馨提示×

您好,登录后才能下订单哦!

密码登录×
登录注册×
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》

如何自定义观察者模式

发布时间:2026-07-18 14:56:43 来源:亿速云 阅读:90 作者:小樊 栏目:编程语言

观察者模式(Observer Pattern)是一种行为型设计模式,用于实现一对多的依赖关系:当一个对象(被观察者)状态发生变化时,所有依赖它的对象(观察者)都会自动收到通知并更新。

下面我从原理 → 自定义实现 → 示例 → 优化建议几个层面来讲,如何自定义观察者模式


一、观察者模式的核心角色

角色 说明
Subject(被观察者) 维护观察者列表,提供注册、移除、通知方法
Observer(观察者) 定义更新接口
ConcreteSubject 具体被观察者
ConcreteObserver 具体观察者

二、最简单的自定义实现(以 Java 为例)

1️⃣ 定义观察者接口

public interface Observer {
    void update(String message);
}

2️⃣ 定义被观察者(Subject)

import java.util.ArrayList;
import java.util.List;

public class Subject {

    private List<Observer> observers = new ArrayList<>();
    private String state;

    // 注册观察者
    public void attach(Observer observer) {
        observers.add(observer);
    }

    // 移除观察者
    public void detach(Observer observer) {
        observers.remove(observer);
    }

    // 通知观察者
    public void notifyObservers() {
        for (Observer observer : observers) {
            observer.update(state);
        }
    }

    // 状态变化
    public void setState(String state) {
        this.state = state;
        notifyObservers();
    }
}

3️⃣ 实现具体观察者

public class ConcreteObserverA implements Observer {
    @Override
    public void update(String message) {
        System.out.println("Observer A 收到消息:" + message);
    }
}

public class ConcreteObserverB implements Observer {
    @Override
    public void update(String message) {
        System.out.println("Observer B 收到消息:" + message);
    }
}

4️⃣ 使用示例

public class Main {
    public static void main(String[] args) {
        Subject subject = new Subject();

        Observer a = new ConcreteObserverA();
        Observer b = new ConcreteObserverB();

        subject.attach(a);
        subject.attach(b);

        subject.setState("状态发生了变化!");
    }
}

三、带事件对象的观察者模式(更通用)

1️⃣ 定义事件对象

public class Event {
    private String type;
    private Object data;

    public Event(String type, Object data) {
        this.type = type;
        this.data = data;
    }

    public String getType() {
        return type;
    }

    public Object getData() {
        return data;
    }
}

2️⃣ 观察者接口接收事件

public interface Observer {
    void onEvent(Event event);
}

3️⃣ 被观察者发送事件

public class Subject {
    private List<Observer> observers = new ArrayList<>();

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

    public void publish(Event event) {
        for (Observer observer : observers) {
            observer.onEvent(event);
        }
    }
}

✅ 这种方式更接近 Spring 事件机制 / GUI 事件机制


四、在 JavaScript 中自定义观察者模式(常用于前端)

class Subject {
  constructor() {
    this.observers = [];
  }

  subscribe(fn) {
    this.observers.push(fn);
  }

  unsubscribe(fn) {
    this.observers = this.observers.filter(obs => obs !== fn);
  }

  notify(data) {
    this.observers.forEach(fn => fn(data));
  }
}

// 使用
const subject = new Subject();

const observer1 = data => console.log('Observer1:', data);
const observer2 = data => console.log('Observer2:', data);

subject.subscribe(observer1);
subject.subscribe(observer2);

subject.notify('数据更新了');

五、常见优化与扩展

✅ 1. 线程安全(Java)

private final List<Observer> observers = 
    Collections.synchronizedList(new ArrayList<>());

或使用 CopyOnWriteArrayList


✅ 2. 观察者按类型订阅(事件总线雏形)

Map<String, List<Observer>>

✅ 3. 避免循环通知 / 死循环

  • 使用标记位
  • 异步通知
  • 限制通知次数

✅ 4. 推模型 vs 拉模型

模型 说明
推模型 Subject 主动把数据推给 Observer ✅
拉模型 Observer 主动从 Subject 拉数据

六、什么时候用观察者模式?

✅ 适合场景:

  • 事件监听(GUI、前端)
  • 消息订阅
  • 状态同步
  • 解耦系统模块

❌ 不适合:

  • 观察者过多导致性能问题
  • 逻辑非常复杂的依赖关系

如果你愿意,我可以:

  • Spring Event 实现
  • Python / C++ / Kotlin 写版本
  • 观察者 vs 发布订阅模式区别

你更想用在哪个场景?

向AI问一下细节

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

AI