首頁 > web前端 > js教程 > JavaScript設計模式:觀察者模式

JavaScript設計模式:觀察者模式

尊渡假赌尊渡假赌尊渡假赌
發布: 2025-02-16 11:00:15
原創
963 人瀏覽過

JavaScript Design Patterns: The Observer Pattern

JavaScript觀察者模式的關鍵要點

  • JavaScript中的觀察者模式允許元素之間進行一對多的數據綁定,這對於保持多個元素與相同數據同步特別有用。
  • 觀察者模式包含三個主要方法:subscribe(添加新的可觀察事件)、unsubscribe(移除可觀察事件)和broadcast(使用綁定數據執行所有事件)。
  • 使用ES6特性(例如類、箭頭函數和常量)可以有效地實現觀察者模式,使代碼更簡潔、更易於重用。
  • 觀察者模式可用於解決JavaScript中的實際問題,例如在每次擊鍵時更新博客文章中的字數統計,並可進一步增強以構建新功能。

在JavaScript中,經常會遇到一個問題:需要一種方法來響應某些事件更新頁面的一部分,並使用這些事件提供的數據。例如,用戶輸入,然後將其投影到一個或多個組件中。這會導致代碼中出現大量的推拉操作以保持所有內容同步。這就是觀察者設計模式可以提供幫助的地方——它實現了元素之間的一對多數據綁定。這種單向數據綁定可以是事件驅動的。使用此模式,您可以構建可重用的代碼來解決您的特定需求。在本文中,我想探討觀察者設計模式。它將幫助您解決在客戶端腳本中經常遇到的一個常見問題。那就是一對多、單向和事件驅動的綁定。當您有很多必須同步的元素時,這個問題經常出現。我將使用ECMAScript 6來說明這種模式。是的,將會有類、箭頭函數和常量。如果您還不熟悉,可以自行探索這些主題。我將只使用ES6中引入語法糖的部分,因此如果需要,它也可以與ES5一起使用。我將使用測試驅動開發(TDD)來處理該模式。這樣,您就可以知道每個組件如何使用。 ES6中的新語言特性使代碼更簡潔。那麼,讓我們開始吧。

事件觀察者

該模式的高級視圖如下所示:

<code>EventObserver
│ 
├── subscribe: 添加新的可观察事件
│ 
├── unsubscribe: 移除可观察事件
│
└── broadcast: 使用绑定数据执行所有事件</code>
登入後複製
登入後複製
登入後複製

在詳細闡述觀察者模式之後,我將添加一個使用它的字數統計功能。字數統計組件將使用此觀察者並將所有內容整合在一起。要初始化EventObserver,請執行以下操作:

class EventObserver {
  constructor() {
    this.observers = [];
  }
}
登入後複製
登入後複製
登入後複製

從一個空的觀察事件列表開始,每個新實例都這樣做。從現在開始,讓我們在EventObserver中添加更多方法來完善設計模式。

subscribe方法

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

subscribe(fn) {
  this.observers.push(fn);
}
登入後複製
登入後複製
登入後複製

獲取觀察事件列表並將新項目推送到數組中。事件列表是回調函數列表。在純JavaScript中測試此方法的一種方法如下:

<code>EventObserver
│ 
├── subscribe: 添加新的可观察事件
│ 
├── unsubscribe: 移除可观察事件
│
└── broadcast: 使用绑定数据执行所有事件</code>
登入後複製
登入後複製
登入後複製

我使用Node斷言在Node中測試此組件。完全相同的斷言也存在於Chai斷言中。請注意,觀察事件列表由簡單的回調組成。然後,我們檢查列表的長度並斷言回調位於列表中。

unsubscribe方法

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

class EventObserver {
  constructor() {
    this.observers = [];
  }
}
登入後複製
登入後複製
登入後複製

從列表中過濾掉與回調函數匹配的任何內容。如果沒有匹配項,則回調將保留在列表中。過濾器返回一個新列表並重新分配觀察者列表。要測試此好方法,請執行以下操作:

subscribe(fn) {
  this.observers.push(fn);
}
登入後複製
登入後複製
登入後複製

回調必須與列表上的相同函數匹配。如果存在匹配項,則unsubscribe方法會將其從列表中移除。請注意,測試使用函數引用來添加和移除它。

broadcast方法

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

// Arrange
const observer = new EventObserver();
const fn = () => {};

// Act
observer.subscribe(fn);

// Assert
assert.strictEqual(observer.observers.length, 1);
登入後複製

這將遍歷觀察事件列表並執行所有回調。有了這個,您就可以獲得與已訂閱事件所需的一對多關係。您可以傳入data參數,這使得回調數據綁定。 ES6使用箭頭函數使代碼更有效。請注意(subscriber) => subscriber(data)函數執行了大部分工作。此單行箭頭函數受益於這種簡短的ES6語法。這是JavaScript編程語言的明顯改進。要測試此broadcast方法,請執行以下操作:

unsubscribe(fn) {
  this.observers = this.observers.filter((subscriber) => subscriber !== fn);
}
登入後複製

使用let而不是const,以便我們可以更改變量的值。這使得變量可變,允許我在回調中重新分配其值。在代碼中使用let向其他程序員發出信號,表明變量在某些時候正在發生變化。這增加了JavaScript代碼的可讀性和清晰度。此測試使我有足夠的信心來確保觀察者按預期工作。使用TDD,一切都是關於在純JavaScript中構建可重用代碼。在純JavaScript中編寫可測試代碼有很多好處。測試所有內容,並保留對代碼重用有益的內容。有了這個,我們已經完善了EventObserver。問題是,您可以用它構建什麼?

觀察者模式的實際應用:博客字數統計演示

對於演示,是時候創建一個博客文章,讓它為您保留字數統計了。您輸入的每個擊鍵都將由觀察者設計模式同步。將其視為自由文本輸入,其中每個事件都會觸發更新到您需要它去的地方。要從自由文本輸入中獲取字數統計,可以執行以下操作:

// Arrange
const observer = new EventObserver();
const fn = () => {};

observer.subscribe(fn);

// Act
observer.unsubscribe(fn);

// Assert
assert.strictEqual(observer.observers.length, 0);
登入後複製

完成了!這個看似簡單的純函數中有很多內容,那麼一個簡單的單元測試怎麼樣?這樣一來,我的意圖就清楚了:

<code>EventObserver
│ 
├── subscribe: 添加新的可观察事件
│ 
├── unsubscribe: 移除可观察事件
│
└── broadcast: 使用绑定数据执行所有事件</code>
登入後複製
登入後複製
登入後複製

請注意blogPost中有點古怪的輸入字符串。我的目的是讓此函數涵蓋盡可能多的邊緣情況。只要它能給我一個正確的字數統計,我們就朝著正確的方向前進。順便說一句,這就是TDD的真正力量。可以迭代此實現並涵蓋盡可能多的用例。單元測試告訴您我期望它的行為。如果行為存在缺陷,無論出於何種原因,都很容易迭代和調整它。通過測試,為其他人留下足夠的證據來進行更改。是時候將這些可重用組件連接到DOM了。這是您將純JavaScript掌握並將其焊接到瀏覽器中的部分。一種方法是在頁面上使用以下HTML:

class EventObserver {
  constructor() {
    this.observers = [];
  }
}
登入後複製
登入後複製
登入後複製

然後是以下JavaScript:

subscribe(fn) {
  this.observers.push(fn);
}
登入後複製
登入後複製
登入後複製

獲取所有可重用代碼並設置觀察者設計模式。這將跟踪文本區域中的更改,並在其下方為您提供字數統計。我正在DOM API中使用body.appendChild()來添加此新元素。然後,附加事件偵聽器以使其栩栩如生。請注意,使用箭頭函數可以連接單行事件。事實上,您可以使用它將事件驅動的更改廣播給所有訂閱者。 () => blogObserver.broadcast()在這裡完成了大部分工作。它甚至將文本區域的最新更改直接傳遞到回調函數中。是的,客戶端腳本非常酷。沒有一個您可以觸摸和調整的演示是完整的,下面是CodePen:(此處應插入CodePen鏈接,由於無法訪問外部網站,無法提供)

現在,我不會稱此功能為完整的功能。但這只是觀察者設計模式的起點。我心中的問題是,您願意走多遠?

展望未來

您可以進一步發展這個想法。您可以使用觀察者設計模式來構建許多新功能。您可以使用以下方法增強演示:

  • 另一個組件計算段落數
  • 另一個組件顯示輸入文本的預覽
  • 使用markdown支持增強預覽,例如

這些只是您可以深入研究的一些想法。上述增強功能將挑戰您的編程能力。

結論

觀察者設計模式可以幫助您解決JavaScript中的實際問題。這解決了保持一堆元素與相同數據同步的長期問題。通常情況下,當瀏覽器觸發特定事件時。我相信你們中的大多數人現在已經遇到了這樣的問題,並且已經轉向工具和第三方依賴項。此設計模式使您能夠走得盡可能遠。在編程中,您將解決方案抽象成模式並構建可重用的代碼。這將帶給您的好處是無限的。我希望您能看到,只需一點紀律和努力,您就可以在純JavaScript中完成多少工作。該語言中的新特性,例如ES6,可以幫助您編寫一些簡潔且可重用的代碼。

(此處應包含JavaScript觀察者模式的常見問題解答,但由於篇幅限制,已省略。)

以上是JavaScript設計模式:觀察者模式的詳細內容。更多資訊請關注PHP中文網其他相關文章!

本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
作者最新文章
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板