JavaScript 之觀察者模式

本文作者爲 360 奇舞團前端開發工程師

概述

在日常開發中,開發人員經常使用設計模式來解決軟件設計中的問題。其中,觀察者模式是一種常用的模式,它可以幫助開發人員更好地處理對象之間的通信。在 JavaScript 中,觀察者模式的應用非常廣泛,可以用於實現事件處理、數據綁定等功能。本文將介紹觀察者模式的基本概念和實現方式。

什麼是觀察者模式?

觀察者模式是一種行爲型設計模式,它定義了一種一對多的依賴關係,讓多個觀察者對象(observer)同時監聽某一個主題對象(subject)。當主題對象發生變化時,它會自動通知所有的觀察者對象,使它們能夠及時更新自己的狀態。

觀察者模式的優點在於它可以實現對象之間的松耦合,使得 Subject 和 Observer 可以獨立地變化,而不會相互影響。它還可以提高代碼的複用性和可維護性,使得代碼更加清晰和易於理解。

事件觀察者

該模式的視圖如下所示:

EventObserver
│ 
├── subscribe: 添加新的可觀察事件
│ 
├── unsubscribe: 移除可觀察事件
|
└── broadcast: 執行帶有綁定數據的所有事件

首先要執行初始化 EventObserver 操作:

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

從觀察到的事件的空列表開始,並對每個新實例執行此操作。

訂閱方法

要添加新事件,請執行以下操作:

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

獲取觀察到的事件列表並將新項目推送到數組中,事件列表是回調函數列表。

要測試這個方法,請執行以下操作:

const fn = () => {};

observer.subscribe(fn);

// Assert
assert.strictEqual(observer.observers.length, 1);

取消訂閱方法

要刪除事件,請執行以下操作:

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

從列表中過濾掉與回調函數匹配的內容。如果沒有匹配,回調將保留在列表中,過濾器返回一個新列表並重新分配觀察者列表。

要測試這個方法,請執行以下操作:

const observer = new EventObserver();
const fn = () ={};

observer.subscribe(fn);

observer.unsubscribe(fn);

// Assert
assert.strictEqual(observer.observers.length, 0);

回調必須與列表中的相同函數匹配,如果存在匹配項,取消訂閱方法會將其從列表中刪除。

廣播法

要調用所有事件,請執行以下操作:

broadcast(data) {
  this.observers.forEach((subscriber) => subscriber(data));
}

這會遍歷觀察到的事件列表並執行所有回調。這樣,你就可以獲得與訂閱事件必要的一對多關係,傳入 data 是回調數據綁定的參數。

要測試這個方法,請執行以下操作:

const observer = new EventObserver();

let subscriberHasBeenCalled = false;
const fn = (data) =subscriberHasBeenCalled = data;

observer.subscribe(fn);

observer.broadcast(true);

// Assert
assert(subscriberHasBeenCalled);

使用 let 而不是 const 這樣我們就可以更改變量的值,這使得變量可變,然後允許我在回調內部重新分配它的值。let 在代碼中會向其他程序員發送一個信號,表明該變量在某個時刻正在發生變化,這樣就增加了 JavaScript 代碼的可讀性和清晰度。

好了,我們已經學會了一個簡單的觀者模式在 javaScript 中的實現。

總結

這篇主要簡單介紹了觀察者模式和其簡單的實現,設計模式還有很多種,例如:單例模式、策略模式、工廠模式等,我們的核心目的是要學習其思想,而不是死記硬背每一種模式的實現方式。只有理解了設計模式的思想,才能在各種業務場景中靈活地應用它們。

參考鏈接

https://www.digitalocean.com/community/tutorial-series/javascript-design-patterns

https://developer.mozilla.org/zh-CN/docs/learn/JavaScript https://zhuanlan.zhihu.com/p/77275289

本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源https://mp.weixin.qq.com/s/hy4A6uv43Ik1GD7LSDjg3Q