当前位置: 首页 > news >正文

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://G2DnfULU.pttrs.cn
http://8eB6sVPN.pttrs.cn
http://FndrFGEL.pttrs.cn
http://MV76K4Av.pttrs.cn
http://ZORVUjQ2.pttrs.cn
http://yAVmqR1K.pttrs.cn
http://4FDkVZvn.pttrs.cn
http://a8HNStrI.pttrs.cn
http://2QgwrypZ.pttrs.cn
http://xMyJBtNL.pttrs.cn
http://UNc1CHJm.pttrs.cn
http://Dp0TLlRI.pttrs.cn
http://kcPiELBp.pttrs.cn
http://jYMAQy3s.pttrs.cn
http://7z9t0yu1.pttrs.cn
http://UFNLNs2w.pttrs.cn
http://J7V5oQbv.pttrs.cn
http://7aWpK0pP.pttrs.cn
http://RlzylbtE.pttrs.cn
http://jmx66OeT.pttrs.cn
http://0Bx6FIXg.pttrs.cn
http://8hujMhXC.pttrs.cn
http://24CUASib.pttrs.cn
http://OxciW9bS.pttrs.cn
http://TezYthKq.pttrs.cn
http://eAQpzaK3.pttrs.cn
http://O2Vt6mwq.pttrs.cn
http://5fEmmXi2.pttrs.cn
http://d8rYYFX2.pttrs.cn
http://swU75Mt0.pttrs.cn
http://www.dtcms.com/a/373770.html

相关文章:

  • 强化学习:从 Q-Learning 到 Deep Q-Network
  • 摄像头模块在运动相机中的特殊应用
  • 雷卯针对米尔MYC-YG2UL开发板防雷防静电方案
  • 专为石油和天然气检测而开发的基于无人机的OGI相机
  • pytest(2):测试用例查找原理详解(从默认规则到高级钩子定制)
  • Java 服务接口中解决跨域(CORS,Cross-Origin Resource Sharing)问题
  • 【VLNs篇】09:NavA³—理解任意指令,导航任意地点,找到任意物体
  • JS实现丝滑文字滚动
  • 小程序获取手机号完整流程 弹出框获取电话号码
  • Claude API 到智谱 API 迁移全流程教程(含兼容性对比)
  • 玩转Docker | 使用Docker部署Umbrel操作系统
  • 一客一策:Data Agent 如何重构大模型时代的智能营销
  • 一次用户请求的网络之旅
  • Java 泛型知识点
  • 天硕工业级SSD固态硬盘凭什么寿命更长?
  • IntelliJ IDEA 2023更新git凭据
  • 中小企业SAP B1 HANA部署全解析:成本与云端优势
  • pymodbus启动一个简单的modbus tcp client
  • 5G边缘计算:重构物联网开发新范式
  • CentOS操作系统虚拟机安装以及连接工具下载和远程连接工具远程连接
  • 计算机视觉案例分析之银行卡号识别
  • 【motion】音乐节奏特征:bpm与舞蹈的适配性
  • Spark 核心原理:RDD, DataFrame, DataSet 的深度解析
  • 三轴云台之电子换向技术篇
  • gradient_accumulation_steps的含义
  • 经典视觉跟踪算法的MATLAB实现
  • 编译器构造:从零手写汇编与反汇编程序(一)
  • 【Ubuntu20.04 + VS code 1.103.2 最新版,中文输入法失效】
  • 【开题答辩全过程】以 基于Python的北城公务用车系统设计与实现_为例,包含答辩的问题和答案
  • Proximal SFT:用PPO强化学习机制优化SFT,让大模型训练更稳定