解释

|880x443

观察者模式 定义了一种一对多的依赖关系。当一个对象(被观察者)的状态发生改变时,所有依赖于它的对象(观察者)都会得到通知自动更新

  • 一句话本质: “别呼叫我,我会呼叫你” (Don’t call us, we’ll call you)。

A1. 要素 (Components)

  1. Subject (目标/被观察者):核心数据源。它手里拿着一份“名单”,记录了谁在关注它。
  2. Observer (观察者):订阅者。它必须提供一个统一的接口(如 update 方法),供 Subject 随时调用。
  3. ConcreteSubject & ConcreteObserver:具体的实现类。

A2. 结构 (Structure)

  • 注册 (Subscribe/Attach):Observer 告诉 Subject:“把你加进我的关注列表”。
  • 通知 (Notify):Subject 遍历名单,逐个调用 Observer 的 update() 方法。
  • 注销 (Unsubscribe/Detach):Observer 告诉 Subject:“取关,别烦我了”。

A3. 系统 (System Function)

当零件组合,该系统实现了**“解耦 (Decoupling)”**: Subject 只知道观察者实现了 Observer 接口,完全不在乎观察者具体是谁(是邮件服务?是前端UI?还是日志系统?)。这使得双方可以独立扩展,互不影响。

Typscript 的实现

interface Subscribe {
    update:()=>void
}
class Target {
    private observers :Subscribe[]= []
    
    public subscribe = function (subscriber:Subscribe){
        const isExit = this.observers.includes(subscriber)
        if(isExit) return console.log('当前已经订阅了')
        
        this.observers.push(subscriber)
        console.log('订阅成功')
    }
    public unsubscribe = function(subscriber:Subscribe) {
     const subscriberIndex = this.observers.indexOf(subscriber);
        if(subscriberIndex === -1) return console.log('没有当前订阅者,退订失败')
        this.observers.slice(subscriberIndex,1)
        console.log('取消订阅成功')
    }
    
    public notify = function (){
        this.observers.forEach( subscriber => {
           subscriber.update() 
        });
    }
}
class Observer implements Subscribe {
    public name :string
    constructor(name:string) {
        this.name = name
    }
    update(): void {
    console.log(`[观察者收到通知-${this.name}]`);
  }
}
 
const target  = new Target()
const mio = new Observer('mio')
const yui = new Observer('yui')
 
//观察者订阅
target.subscribe(mio)
target.subscribe(yui)
 
target.notify()

具体案例参考

构建自己的Redux 构建自己的Tanstack Quary

reference

https://refactoringguru.cn/design-patterns/observer