TypeScript實現設計模式——觀察者模式


觀察者模式是一種行為設計模式,允許一個對象將其狀態的改變通知其他對象。

觀察者模式提供了一種作用於任何實現了訂閱者接口的對象的機制, 可對其事件進行訂閱和取消訂閱。

圖片來源:https://refactoringguru.cn/design-patterns/observer

觀察者模式是一種在前端領域應用十分廣泛的設計模式,特別是在圖形界面的組件中,如果你自定義了一個按鈕組件,那么你很可能需要用到觀察者模式。

觀察者模式的核心成員有兩個,一個是作為事件發布者的Subject類,另一個是作為事件接收者的Observer類。

Subject部分

Subject類所具有的公共部分是對訂閱者的管理和向所有訂閱者發布消息,而具體Subject所負責的業務邏輯需要放到各自的Subject類中。

Subject接口

interface Subject {
  // 添加觀察者
  attach(observer: Observer): void;
  // 移除觀察者
  detach(observer: Observer): void;
  // 通知所有觀察者
  notify(): void;
}

具體Subject類

class ConcreteSubject implements Subject {
  // 發布者狀態,測試使用
  public state: number;

  // 訂閱者名單
  public observers: Array<Observer> = [];

  // 管理訂閱方法
  public attach(observer: Observer): void {
    const observerIndex = this.observers.indexOf(observer);
    if (observerIndex !== -1) {
      return console.log('已訂閱');
    }

    this.observers.push(observer);
    console.log('訂閱成功');
  }

  public detach(observer: Observer): void {
    const observerIndex = this.observers.indexOf(observer);
    if (observerIndex === -1) {
      return console.log('訂閱者未訂閱');
    }

    this.observers.splice(observerIndex, 1);
    console.log('訂閱者已移除');
  }

  public notify(): void {
    console.log('通知所有訂閱者');
    for (const observer of this.observers) {
      observer.update(this);
    }
  }
    
  // 訂閱管理以外的邏輯
  public someLogic() {
    this.state = Math.floor(Math.random() * 10 + 1);

    console.log(`我更改了我的狀態:state=${this.state}`);
    this.notify();
  }
}

Observer部分

觀察者只需要根據發布者的發出的消息來判斷自己是否需要做出回應即可。

Observer接口

interface Observer {
  // 對發布者發出的更新消息作出回應
  update(subject: Subject): void;
}

具體Observer類

//具體觀察者A
class ConcreteObserverA implements Observer {
  public update(subject: ConcreteSubject) {
    if (subject.state <= 5) {
      console.log('觀察者A作出回應');
    }
  }
}

// 具體觀察者B
class ConcreteObserverB implements Observer {
  public update(subject: ConcreteSubject) {
    if (subject.state > 5) {
      console.log('觀察者B作出回應');
    }
  }
}

測試代碼

因為是隨機數,可能會得不到想要的結果,可以多嘗試幾次

const subject = new ConcreteSubject();

const observerA = new ConcreteObserverA();
subject.attach(observerA);

const observerB = new ConcreteObserverB();
subject.attach(observerB);

subject.someLogic();

subject.detach(observerB);

subject.someLogic();


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM