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 的显示状态等。