JavaScript 行為型設計模式詳解

1. 觀察者模式

1.1.?使用場景

觀察者模式用于對象間的一對多依賴關系,當一個對象的狀態發生變化時,所有依賴于它的對象都能收到通知并自動更新。常用于事件處理、通知系統。在前端中,觀察者模式用于實現事件監聽、數據綁定等功能。

1.2.?代碼實現

class Subject {constructor() {this.observers = [];}addObserver(observer) {this.observers.push(observer);}removeObserver(observer) {this.observers = this.observers.filter(obs => obs !== observer);}notifyObservers(message) {this.observers.forEach(observer => observer.update(message));}
}class Observer {update(message) {console.log('Observer received:', message);}
}// 使用觀察者模式
const subject = new Subject();
const observer1 = new Observer();
const observer2 = new Observer();subject.addObserver(observer1);
subject.addObserver(observer2);subject.notifyObservers('New update available'); // Observer received: New update available

1.3.?詳細解釋

  • Subject:發布者,維護一個觀察者列表,提供方法來添加、移除和通知觀察者。

  • Observer:觀察者,提供 update 方法來響應發布者的通知。

  • 觀察者模式適合事件系統或數據模型更新的場景。

1.4.?實際應用

觀察者模式常用于事件驅動系統,如 DOM 事件監聽器、Vue 或 React 的響應式系統。

2. 發布訂閱模式

2.1.?使用場景

發布訂閱模式用于實現松耦合的事件驅動系統,發布者(Publisher)和訂閱者(Subscriber)通過事件中心(Event Bus或Broker)進行通信,發布者無需知道誰訂閱了事件,而訂閱者也無需知道事件由誰發布。該模式常用于消息隊列、事件系統、異步處理等場景。

2.2.?代碼實現

// 事件中心(Event Bus)
class EventBus {constructor() {this.subscribers = {}; // 存儲所有事件和其對應的訂閱者}// 訂閱事件subscribe(event, callback) {if (!this.subscribers[event]) {this.subscribers[event] = []; // 如果事件不存在,創建一個新的訂閱者列表}this.subscribers[event].push(callback); // 將訂閱者的回調函數加入列表}// 發布事件publish(event, data) {if (this.subscribers[event]) {this.subscribers[event].forEach(callback => callback(data)); // 通知所有訂閱者}}// 取消訂閱unsubscribe(event, callback) {if (this.subscribers[event]) {this.subscribers[event] = this.subscribers[event].filter(cb => cb !== callback); // 移除指定的訂閱者}}
}// 創建事件中心
const eventBus = new EventBus();// 訂閱者1
const subscriber1 = (data) => {console.log('Subscriber 1 received:', data);
};// 訂閱者2
const subscriber2 = (data) => {console.log('Subscriber 2 received:', data);
};// 訂閱事件
eventBus.subscribe('eventA', subscriber1);
eventBus.subscribe('eventA', subscriber2);// 發布事件
eventBus.publish('eventA', 'This is event A data');
// Subscriber 1 received: This is event A data
// Subscriber 2 received: This is event A data// 取消訂閱者2的訂閱
eventBus.unsubscribe('eventA', subscriber2);// 再次發布事件
eventBus.publish('eventA', 'This is new event A data');
// Subscriber 1 received: This is new event A data

2.3.?詳細注釋

  • EventBus(事件中心):作為中介,維護一個事件和訂閱者的映射關系。負責發布事件、添加訂閱者以及移除訂閱者。

  • subscribe:用于訂閱某個事件,將訂閱者的回調函數加入到對應事件的訂閱者列表中。

  • publish:用于發布某個事件,觸發該事件的所有訂閱者的回調函數。

  • unsubscribe:取消訂閱某個事件,移除指定訂閱者的回調函數。

2.4.?實際應用

  • 在前端開發中,發布訂閱模式常用于事件中心管理事件流,比如在 Vue.js 的 emit和on 中。

  • 消息隊列系統(如 RabbitMQ、Kafka)也是發布訂閱模式的典型應用。

3. 模板方法模式

3.1.?使用場景

模板方法模式定義了一個操作中的算法骨架,而將一些步驟的實現延遲到子類。常用于固定流程中部分步驟需要定制的場景。在前端中,模板方法模式可用于不同頁面之間的結構共享。

3.2.?代碼實現

class AbstractClass {templateMethod() {this.step1();this.step2();this.step3();}step1() {console.log('AbstractClass: Step 1');}step2() {throw new Error('step2 must be implemented by subclass');}step3() {console.log('AbstractClass: Step 3');}
}class ConcreteClass extends AbstractClass {step2() {console.log('ConcreteClass: Step 2');}
}// 使用模板方法模式
const instance = new ConcreteClass();
instance.templateMethod();
// Output:
// AbstractClass: Step 1
// ConcreteClass: Step 2
// AbstractClass: Step 3

3.3. 詳細注釋

  • AbstractClass:提供算法的骨架,定義了 templateMethod 作為算法的模板方法,具體步驟由子類實現。

  • ConcreteClass:子類實現了模板方法中的具體步驟。

  • 模板方法模式允許子類在不改變算法整體結構的前提下,重新定義算法的某些步驟。

3.4.?實際應用

  • 模板方法模式常用于頁面加載邏輯、復雜流程處理等場景,如表單驗證步驟、數據處理流程等。

4. 策略模式

4.1.?使用場景

策略模式定義了一系列算法,并將每個算法封裝起來,使它們可以互換使用。在前端開發中,策略模式可以用于處理不同的用戶輸入、動態選擇不同的 UI 渲染邏輯等。

4.2.?代碼實現

class StrategyA {execute() {console.log('Executing Strategy A');}
}class StrategyB {execute() {console.log('Executing Strategy B');}
}class Context {setStrategy(strategy) {this.strategy = strategy;}executeStrategy() {this.strategy.execute();}
}// 使用策略模式
const context = new Context();
const strategyA = new StrategyA();
context.setStrategy(strategyA);
context.executeStrategy(); // Executing Strategy Aconst strategyB = new StrategyB();
context.setStrategy(strategyB);
context.executeStrategy(); // Executing Strategy B

4.3.?詳細注釋

  • StrategyA 和 StrategyB:定義了不同的算法實現。

  • Context:上下文類,維護當前策略,并通過 setStrategy 方法動態切換策略。

  • 策略模式允許在運行時根據條件選擇不同的算法,避免使用大量條件語句。

4.4.?實際應用

  • 策略模式常用于表單驗證、輸入處理、動態 UI 渲染等場景。

5. 責任鏈模式

5.1.?使用場景

責任鏈模式用于將請求的處理者串聯起來,多個對象依次處理請求,直到有對象處理它為止。在前端中,責任鏈模式常用于事件處理鏈、表單驗證流程等。

5.2.?代碼實現

class Handler {setNext(handler) {this.nextHandler = handler;}handle(request) {if (this.nextHandler) {return this.nextHandler.handle(request);}return null;}
}class ConcreteHandlerA extends Handler {handle(request) {if (request === 'A') {return 'Handled by A';}return super.handle(request);}
}class ConcreteHandlerB extends Handler {handle(request) {if (request === 'B') {return 'Handled by B';}return super.handle(request);}
}// 使用責任鏈模式
const handlerA = new ConcreteHandlerA();
const handlerB = new ConcreteHandlerB();
handlerA.setNext(handlerB);console.log(handlerA.handle('A')); // Handled by A
console.log(handlerA.handle('B')); // Handled by B

5.3.?詳細注釋

  • Handler:處理者的基類,提供 setNext 方法來設置下一個處理者。

  • ConcreteHandlerA 和 ConcreteHandlerB:具體處理者,實現了請求處理邏輯。

  • 責任鏈模式使得多個處理者依次處理請求,避免了請求和處理者之間的緊耦合。

5.4.?實際應用

  • 責任鏈模式常用于表單驗證、事件處理鏈、權限管理等場景。

6. 中介者模式

6.1.?使用場景

中介者模式用于定義對象間的通信方式,避免直接交互造成的復雜性。在前端中,中介者模式常用于組件之間的通信、事件總線等。

6.2.?代碼實現

class Mediator {notify(sender, event) {if (event === 'EventA') {console.log('Mediator reacts to EventA and triggers EventB');sender.trigger('EventB');}}
}class Component {constructor(mediator) {this.mediator = mediator;}trigger(event) {console.log(`Component triggered: ${event}`);this.mediator.notify(this, event);}
}// 使用中介者模式
const mediator = new Mediator();
const component = new Component(mediator);component.trigger('EventA');/* Output:
Component triggered: EventA
Mediator reacts to EventA and triggers EventB
Component triggered: EventB
*/

6.3.?詳細注釋

  • Mediator:中介者類,負責協調不同組件之間的交互。

  • Component:組件類,負責觸發事件并通過中介者進行通信。

  • 中介者模式通過集中化的中介者,避免了多個組件之間的復雜依賴關系。

6.4.?實際應用

  • 中介者模式常用于組件通信、消息總線、事件系統等場景。

7. 訪問者模式

7.1.?使用場景

訪問者模式用于在不改變數據結構的前提下,定義對數據結構中元素的操作。在前端中,訪問者模式適用于復雜結構的遍歷和操作,如 DOM 樹操作等。

7.2.?代碼實現

class Element {accept(visitor) {visitor.visit(this);}
}class ConcreteElementA extends Element {operationA() {console.log('Operation A');}
}class ConcreteElementB extends Element {operationB() {console.log('Operation B');}
}class Visitor {visit(element) {if (element instanceof ConcreteElementA) {element.operationA();} else if (element instanceof ConcreteElementB) {element.operationB();}}
}// 使用訪問者模式
const elements = [new ConcreteElementA(), new ConcreteElementB()];
const visitor = new Visitor();
elements.forEach(element => element.accept(visitor));

7.3.?詳細注釋

  • Element:元素基類,定義 accept 方法來接受訪問者。

  • Visitor:訪問者類,提供 visit 方法處理不同的元素類型。

  • 訪問者模式允許在不修改數據結構的前提下,動態為結構中的每個元素定義新的操作。

7.4.?實際應用

  • 訪問者模式常用于對樹形結構、DOM 元素的遍歷操作。

8. 命令模式

8.1.?使用場景

命令模式用于將請求封裝為對象,從而實現請求的參數化、隊列化。在前端中,命令模式適用于實現操作歷史、撤銷功能等場景。

8.2.?代碼實現

class Command {execute() {throw new Error('execute method must be implemented');}
}class ConcreteCommand extends Command {constructor(receiver) {super();this.receiver = receiver;}execute() {this.receiver.action();}
}class Receiver {action() {console.log('Receiver action executed');}
}class Invoker {setCommand(command) {this.command = command;}executeCommand() {this.command.execute();}
}// 使用命令模式
const receiver = new Receiver();
const command = new ConcreteCommand(receiver);
const invoker = new Invoker();invoker.setCommand(command);
invoker.executeCommand(); // Receiver action executed

8.3. 詳細注釋

  • Command:命令的基類,定義 execute 方法。

  • ConcreteCommand:具體命令,執行對接收者的操作。

  • Invoker:調用者,負責執行命令。

  • 命令模式通過封裝請求,將請求處理邏輯與請求發出者解耦。

8.4.?實際應用

  • 命令模式常用于實現操作歷史、撤銷重做、宏命令等場景。

9. 解釋器模式

9.1.?使用場景

解釋器模式用于給定語言的語法表達式,并解析其中的語句。在前端中,解釋器模式可用于解析自定義的模板語言、腳本等。

9.2.?代碼實現

class Expression {interpret(context) {throw new Error('interpret method must be implemented');}
}class NumberExpression extends Expression {constructor(value) {super();this.value = value;}interpret() {return this.value;}
}class AddExpression extends Expression {constructor(left, right) {super();this.left = left;this.right = right;}interpret() {return this.left.interpret() + this.right.interpret();}
}// 使用解釋器模式
const left = new NumberExpression(3);
const right = new NumberExpression(5);
const addExpr = new AddExpression(left, right);console.log(addExpr.interpret()); // 8

9.3.?詳細注釋

  • Expression:解釋器基類,定義 interpret 方法。

  • NumberExpression 和 AddExpression:具體的解釋器,解析數字和加法操作。

  • 解釋器模式允許定義一個簡單的語言或規則,并通過解釋器解析和執行。

9.4.?實際應用

  • 解釋器模式常用于處理模板引擎、正則表達式解析等場景。

10. 迭代器模式

10.1.?使用場景

迭代器模式用于順序訪問集合對象的元素,而無需暴露其內部結構。在前端中,迭代器模式常用于遍歷數組、集合等數據結構。

10.2.?代碼實現

class Iterator {constructor(collection) {this.collection = collection;this.index = 0;}hasNext() {return this.index < this.collection.length;}next() {return this.collection[this.index++];}
}// 使用迭代器模式
const collection = [1, 2, 3, 4];
const iterator = new Iterator(collection);while (iterator.hasNext()) {console.log(iterator.next()); // 1 2 3 4
}

10.3.?詳細注釋

  • Iterator:迭代器類,提供 hasNext 和 next 方法來順序訪問集合中的元素。

  • 迭代器模式允許分離集合對象的遍歷邏輯,使得遍歷和數據結構解耦。

10.4.?實際應用

  • 迭代器模式常用于處理數組、鏈表、樹等數據結構的遍歷。

11. 備忘錄模式

11.1.?使用場景

備忘錄模式用于保存對象的狀態,以便在需要時恢復。在前端中,備忘錄模式可用于實現撤銷功能、保存表單狀態等。

11.2.?代碼實現

class Memento {constructor(state) {this.state = state;}getState() {return this.state;}
}class Originator {setState(state) {console.log('Setting state to:', state);this.state = state;}saveStateToMemento() {return new Memento(this.state);}getStateFromMemento(memento) {this.state = memento.getState();}
}class Caretaker {constructor() {this.mementoList = [];}
}// 使用備忘錄模式
const originator = new Originator();
const caretaker = new Caretaker();originator.setState('State 1');
caretaker.add(originator.saveStateToMemento());originator.setState('State 2');
caretaker.add(originator.saveStateToMemento());originator.setState('State 3');
console.log('Current State:', originator.state); // Current State: State 3originator.getStateFromMemento(caretaker.get(0));
console.log('Restored State:', originator.state); // Restored State: State 1

11.3.?詳細注釋

  • Memento:備忘錄類,保存狀態。

  • Originator:原始對象,提供保存和恢復狀態的方法。

  • Caretaker:管理備忘錄列表。

  • 備忘錄模式通過保存對象的狀態,允許在需要時恢復之前的狀態。

11.4.?實際應用

  • 備忘錄模式常用于實現撤銷功能、表單狀態恢復等場景。

12. 狀態模式

12.1.?使用場景

狀態模式允許對象在內部狀態發生改變時,改變其行為。在前端中,狀態模式可用于管理復雜的組件狀態,如表單驗證、UI 狀態管理等。

12.2.?代碼實現

class State {handle(context) {throw new Error('handle method must be implemented');}
}class ConcreteStateA extends State {handle(context) {console.log('State A, transitioning to State B');context.setState(new ConcreteStateB());}
}class ConcreteStateB extends State {handle(context) {console.log('State B, transitioning to State A');context.setState(new ConcreteStateA());}
}class Context {constructor() {this.state = new ConcreteStateA();}setState(state) {this.state = state;}request() {this.state.handle(this);}
}// 使用狀態模式
const context = new Context();
context.request(); // State A, transitioning to State B
context.request(); // State B, transitioning to State A

12.3.?詳細注釋

  • State:狀態基類,定義 handle 方法。

  • ConcreteStateA 和 ConcreteStateB:具體狀態類,實現了狀態切換邏輯。

  • Context:上下文類,負責在不同狀態下切換并調用狀態行為。

  • 狀態模式允許對象在狀態變化時改變其行為,使得狀態切換透明化。

12.4.?實際應用

  • 狀態模式常用于處理復雜的狀態邏輯,如表單的驗證狀態、UI 的顯示狀態等。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/921647.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/921647.shtml
英文地址,請注明出處:http://en.pswp.cn/news/921647.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

指令查找表LUT

本文整理自22. FlexSPI—讀寫外部SPI NorFlash — [野火]i.MX RT庫開發實戰指南——基于i.MXRT1052 文檔 用作個人學習和分享 指令查找表LUT 訪問FLASH存儲器通常包含一些讀寫功能的的控制指令&#xff0c;主控設備可通過這些指令訪問FLASH存儲器。 為了適應這種需求&#…

uv使用指南

&#x1f680; Python 打包工具 UV 使用指南 UV 是一個用 Rust 編寫的極速 Python 包管理器和解析器&#xff0c;旨在成為 pip、pip-tools、virtualenv 等工具的單一替代方案。 &#x1f4cb; 目錄 核心概念與設計哲學安裝與配置基礎使用方法項目管理與工作流高級功能與技巧…

安卓學習 之 圖片控件和圖片按鈕

今天學習的是ImageView 和 ImageButton這兩個控件還是比較簡單的&#xff1a;先來看看最后的樣式圖片吧&#xff1a;從圖片中可以看到ImageView中的圖片要大很多&#xff0c;這是因為中的ImageView中的圖片跟ImageView控件的大小而自動調整。Imag…

動態規劃-學習筆記

這是一份動態規劃&#xff08;Dynamic Programming, DP&#xff09;完整學習筆記。筆記將從一星難度&#xff08;入門&#xff09;到五星難度&#xff08;進階&#xff09;&#xff0c;循序漸進&#xff0c;涵蓋核心思想、經典模型和解題方法論。 本來打算今天更新背包問題的題…

Linux 可信啟動深度解析:從UEFI到操作系統的信任鏈

文章目錄引言一、 可信根基&#xff1a;TPM與核心概念1.1 什么是“度量” (Measurement)&#xff1f;1.2 信任鏈與TPM PCR二、 階段一&#xff1a;固件的可信啟動 (UEFI)2.1 引導的起點&#xff1a;從SEC到DXE的初始化2.2 引導設備選擇 (BDS)&#xff1a;UEFI如何找到GRUB2.3 S…

61-python中面向對象三大特性

前言&#xff1a; 面向對象編程&#xff0c;是許多編程語言都支持的一種編程思想。簡單理解是&#xff1a;基于模板&#xff08;類&#xff09;去創建實體&#xff08;對象&#xff09;&#xff0c; 使用對象完成功能開發。面向對象包含三大主要特性&#xff1a; 封裝 繼承 多態…

BP-Adaboost模型

BP-Adaboost模型是一種將BP神經網絡作為弱分類器的集成學習框架&#xff0c;通過AdaBoost算法動態調整樣本權重和模型權重&#xff0c;顯著提升預測精度和泛化能力。一、模型架構與工作原理 1. 基礎框架 弱分類器單元&#xff1a;采用單隱藏層BP神經網絡&#xff08;結構示例&a…

k230 +canMV+ LVGL控件 仿手表表盤觸摸屏滾動、選中后彈窗效果完整示例程序

現在智能手表用的越來越多,其交互方式比較有特點,現在k230開發板上,基于LVGL(Light and Versatile Graphics Library)編寫一個嵌入式GUI應用程序,使用LVGL配合觸摸屏實現模仿智能手表的表盤滾動效果,實際效果如下: 程序使用LVGL圖形庫和MediaManager程序,創建帶有觸摸…

使用Vue.js和WebSocket打造實時庫存儀表盤

大家好&#xff01;今天我將分享一個簡單卻強大的實時庫存儀表盤項目&#xff0c;基于Vue.js和WebSocket技術。這個項目適合初學者學習前端實時數據處理&#xff0c;也能為你的技術博客或作品集增添亮點&#xff01;通過這個教程&#xff0c;你將學會如何使用WebSocket實現實時…

leecode100——接雨水

題目 雙指針 思路1 使用參數存儲從左往右&#xff08;從右往左同理&#xff09;遍歷時的最高的柱子&#xff0c; 然后移動左右的指針&#xff0c;每次移動左右指針中偏向小的&#xff0c; 如果當前指針指的柱子小于最高的柱子&#xff0c;就會存在接到水。 思路2 把水看作柱子&…

復古膠片風格街拍人像Lr調色教程,手機濾鏡PS+Lightroom預設下載!

調色教程復古膠片風格街拍人像 Lightroom 調色&#xff0c;通過模擬經典膠片相機的色彩科學&#xff0c;為現代數碼照片注入懷舊韻味。這種調色手法注重低飽和度色彩、柔和的高光過渡和豐富的暗部細節&#xff0c;配合適度的顆粒感&#xff0c;營造出時光沉淀的質感。特別適合街…

Linux的gpio子系統

GPIO其實也是某個pin的功能之一。上一小節講解了 pinctrl 子系統&#xff0c;pinctrl 子系統重點是設置 PIN(有的 SOC 叫做 PAD)的復用和電氣屬性&#xff0c;如果 pinctrl 子系統將一個 PIN 復用為 GPIO 的話&#xff0c;那么接下來就要用到 gpio 子系統了。gpio 子系統顧名思…

VC++ CPU指令集檢測工具實現原理

&#x1f4c8; VC CPU指令集檢測工具實現原理 例圖&#xff1a;&#x1f9e0; 1. 核心原理&#xff1a;CPUID指令 // 使用CPUID指令獲取CPU信息 int cpuInfo[4] { -1 }; __cpuid(cpuInfo, 0); // 調用CPUID指令 int nIds cpuInfo[0]; // 獲取最大標準功能號CPUID指令工作流程…

大模型微調理論、實戰:LLaMA-Factory、Unsloth

概述 微調&#xff0c;Fine-Tuning&#xff0c;簡稱FT&#xff0c;可理解為對LLM的定制&#xff0c;目的是增強專業領域知識&#xff0c;并優化特定任務的性能。通過在特定數據集上微調一個預訓練模型&#xff0c;可實現&#xff1a; 更新知識&#xff1a;引入新的領域專屬信…

【LCA 樹上倍增】P9245 [藍橋杯 2023 省 B] 景區導游|普及+

本文涉及知識點 樹上倍增 P9245 [藍橋杯 2023 省 B] 景區導游 題目描述 某景區一共有 NNN 個景點&#xff0c;編號 111 到 NNN。景點之間共有 N?1N-1N?1 條雙向的擺渡車線路相連&#xff0c;形成一棵樹狀結構。在景點之間往返只能通過這些擺渡車進行&#xff0c;需要花費…

基于Python+Streamlit的旅游數據分析與預測系統:從數據可視化到機器學習預測的完整實現

&#x1f3de;? 基于PythonStreamlit的旅游數據分析與預測系統&#xff1a;從數據可視化到機器學習預測的完整實現 &#x1f4dd; 前言 在大數據時代&#xff0c;旅游行業的數據分析變得越來越重要。如何從海量的旅游數據中挖掘有價值的信息&#xff0c;并進行準確的銷量預測&…

飛算JavaAI全鏈路實戰:智能構建高可用電商系統核心架構

飛算JavaAI全鏈路實戰&#xff1a;智能構建高可用電商系統核心架構 前言&#xff1a;AI編程新時代的電商系統開發范式變革 在當今數字經濟時代&#xff0c;電商系統作為企業數字化轉型的核心載體&#xff0c;其復雜度和技術要求與日俱增。一個完整的電商系統不僅需要處理商品、…

論文精讀(五):面向鏈接預測的知識圖譜表示學習方法綜述

筆者鏈接&#xff1a;撲克中的黑桃A 專欄鏈接&#xff1a;論文精讀 本文關鍵詞&#xff1a;知識圖譜; 表示學習; 鏈接預測; 多元關系; 超關系 引 諸位技術同仁&#xff1a; 本系列將系統精讀的方式&#xff0c;深入剖析計算機科學頂級期刊/會議論文&#xff0c;聚焦前沿突破…

Roo Code之自定義指令(Custom Instructions),規則(Rules)

在Roo Code 中&#xff0c;Custom Instructions 可以通過Instructions 設定和Rules 規則文件實現。什么是Custom Instructions&#xff1f; 自定義指令(Custom Instructions)定義了超出Roo基本角色定義范圍的具體行為、偏好和約束。示例包括編碼風格、文檔標準、測試要求和工作…

9/8我是ai大師

一、變量定義部分&#xff08;理解程序的 "記憶"&#xff09;c運行/* USER CODE BEGIN PV */ static uint8_t last_button_state 1; // 初始為高電平&#xff08;未按下&#xff09; static uint8_t device_mode 0; // 設備模式&#xff1a;0LD1, 1LD3, 2蜂鳴器, 3…