33-js-concepts设计模式:23种设计模式在JavaScript中的应用
前言:为什么JavaScript开发者需要掌握设计模式?
在当今快速发展的Web开发领域,JavaScript已成为最核心的编程语言之一。随着项目规模的不断扩大和复杂度的提升,如何编写可维护、可扩展、可重用的代码成为了每个开发者必须面对的挑战。
设计模式(Design Patterns)正是解决这一问题的关键工具。它们代表了软件开发中经过验证的最佳实践,能够帮助我们构建更加健壮和灵活的应用程序。本文将深入探讨23种经典设计模式在JavaScript中的具体应用,帮助你在实际开发中游刃有余。
设计模式分类概览
根据GoF(Gang of Four)的经典分类,设计模式可以分为三大类:
创建型模式(Creational Patterns)
专注于对象创建机制,提供灵活的对象创建方式
结构型模式(Structural Patterns)
关注类和对象的组合,形成更大的结构
行为型模式(Behavioral Patterns)
关注对象之间的通信和职责分配
一、创建型设计模式详解
1. 单例模式(Singleton Pattern)
应用场景:全局状态管理、配置对象、日志记录器
class Singleton {
constructor() {
if (!Singleton.instance) {
Singleton.instance = this;
}
return Singleton.instance;
}
static getInstance() {
if (!Singleton.instance) {
Singleton.instance = new Singleton();
}
return Singleton.instance;
}
}
// 使用示例
const instance1 = Singleton.getInstance();
const instance2 = Singleton.getInstance();
console.log(instance1 === instance2); // true
2. 工厂方法模式(Factory Method Pattern)
应用场景:创建复杂对象、依赖注入、对象池
class VehicleFactory {
createVehicle(type) {
switch(type) {
case 'car':
return new Car();
case 'bike':
return new Bike();
case 'truck':
return new Truck();
default:
throw new Error('Unknown vehicle type');
}
}
}
class Car {
drive() {
return 'Driving a car';
}
}
class Bike {
ride() {
return 'Riding a bike';
}
}
// 使用示例
const factory = new VehicleFactory();
const car = factory.createVehicle('car');
console.log(car.drive()); // Driving a car
3. 抽象工厂模式(Abstract Factory Pattern)
应用场景:创建相关对象家族、跨平台UI组件
class UIFactory {
createButton() {}
createCheckbox() {}
}
class WindowsFactory extends UIFactory {
createButton() {
return new WindowsButton();
}
createCheckbox() {
return new WindowsCheckbox();
}
}
class MacFactory extends UIFactory {
createButton() {
return new MacButton();
}
createCheckbox() {
return new MacCheckbox();
}
}
// 具体产品类
class WindowsButton {
render() {
return 'Windows style button';
}
}
class MacButton {
render() {
return 'Mac style button';
}
}
4. 建造者模式(Builder Pattern)
应用场景:创建复杂对象、配置选项众多的情况
class PizzaBuilder {
constructor() {
this.pizza = {};
}
setSize(size) {
this.pizza.size = size;
return this;
}
setCrust(crust) {
this.pizza.crust = crust;
return this;
}
addTopping(topping) {
if (!this.pizza.toppings) {
this.pizza.toppings = [];
}
this.pizza.toppings.push(topping);
return this;
}
build() {
return this.pizza;
}
}
// 使用示例
const pizza = new PizzaBuilder()
.setSize('large')
.setCrust('thin')
.addTopping('cheese')
.addTopping('pepperoni')
.build();
5. 原型模式(Prototype Pattern)
应用场景:对象克隆、性能优化、减少对象创建开销
class Prototype {
constructor() {
this.value = 'default';
}
clone() {
const clone = Object.create(Object.getPrototypeOf(this));
Object.assign(clone, this);
return clone;
}
}
// 使用示例
const original = new Prototype();
original.value = 'custom';
const clone = original.clone();
console.log(clone.value); // 'custom'
二、结构型设计模式详解
6. 适配器模式(Adapter Pattern)
应用场景:接口兼容、第三方库集成、遗留代码改造
// 旧接口
class OldCalculator {
operations(term1, term2, operation) {
switch(operation) {
case 'add':
return term1 + term2;
case 'sub':
return term1 - term2;
default:
return NaN;
}
}
}
// 新接口
class NewCalculator {
add(term1, term2) {
return term1 + term2;
}
sub(term1, term2) {
return term1 - term2;
}
}
// 适配器
class CalculatorAdapter {
constructor() {
this.newCalculator = new NewCalculator();
}
operations(term1, term2, operation) {
switch(operation) {
case 'add':
return this.newCalculator.add(term1, term2);
case 'sub':
return this.newCalculator.sub(term1, term2);
default:
return NaN;
}
}
}
7. 桥接模式(Bridge Pattern)
应用场景:抽象与实现分离、多维度变化
// 实现部分
class Renderer {
renderCircle(radius) {}
}
class VectorRenderer extends Renderer {
renderCircle(radius) {
return `Drawing a circle of radius ${radius} as vector`;
}
}
class RasterRenderer extends Renderer {
renderCircle(radius) {
return `Drawing a circle of radius ${radius} as pixels`;
}
}
// 抽象部分
class Shape {
constructor(renderer) {
this.renderer = renderer;
}
draw() {}
resize(factor) {}
}
class Circle extends Shape {
constructor(renderer, radius) {
super(renderer);
this.radius = radius;
}
draw() {
return this.renderer.renderCircle(this.radius);
}
resize(factor) {
this.radius *= factor;
}
}
8. 组合模式(Composite Pattern)
应用场景:树形结构、文件系统、UI组件层级
class Component {
constructor(name) {
this.name = name;
}
operation() {}
add(component) {}
remove(component) {}
getChild(index) {}
}
class Leaf extends Component {
operation() {
return `Leaf: ${this.name}`;
}
}
class Composite extends Component {
constructor(name) {
super(name);
this.children = [];
}
operation() {
const results = [];
for (const child of this.children) {
results.push(child.operation());
}
return `Branch: ${this.name} (${results.join(', ')})`;
}
add(component) {
this.children.push(component);
}
remove(component) {
const index = this.children.indexOf(component);
if (index !== -1) {
this.children.splice(index, 1);
}
}
getChild(index) {
return this.children[index];
}
}
9. 装饰器模式(Decorator Pattern)
应用场景:功能扩展、AOP编程、中间件
class Coffee {
cost() {
return 5;
}
description() {
return 'Simple coffee';
}
}
class MilkDecorator {
constructor(coffee) {
this.coffee = coffee;
}
cost() {
return this.coffee.cost() + 2;
}
description() {
return this.coffee.description() + ', milk';
}
}
class SugarDecorator {
constructor(coffee) {
this.coffee = coffee;
}
cost() {
return this.coffee.cost() + 1;
}
description() {
return this.coffee.description() + ', sugar';
}
}
// 使用示例
let coffee = new Coffee();
coffee = new MilkDecorator(coffee);
coffee = new SugarDecorator(coffee);
console.log(coffee.description()); // Simple coffee, milk, sugar
console.log(coffee.cost()); // 8
10. 外观模式(Facade Pattern)
应用场景:简化复杂子系统、提供统一接口
class CPU {
freeze() { console.log('CPU freeze'); }
jump(position) { console.log(`CPU jump to ${position}`); }
execute() { console.log('CPU execute'); }
}
class Memory {
load(position, data) {
console.log(`Memory load at ${position}: ${data}`);
}
}
class HardDrive {
read(lba, size) {
console.log(`HardDrive read LBA ${lba}, size ${size}`);
return 'boot data';
}
}
// 外观类
class ComputerFacade {
constructor() {
this.cpu = new CPU();
this.memory = new Memory();
this.hardDrive = new HardDrive();
}
start() {
this.cpu.freeze();
const bootData = this.hardDrive.read(0, 1024);
this.memory.load(0, bootData);
this.cpu.jump(0);
this.cpu.execute();
}
}
// 使用示例
const computer = new ComputerFacade();
computer.start();
11. 享元模式(Flyweight Pattern)
应用场景:大量相似对象、内存优化、缓存
class FlyweightFactory {
constructor() {
this.flyweights = {};
}
getFlyweight(key) {
if (!this.flyweights[key]) {
this.flyweights[key] = new ConcreteFlyweight(key);
}
return this.flyweights[key];
}
getCount() {
return Object.keys(this.flyweights).length;
}
}
class ConcreteFlyweight {
constructor(intrinsicState) {
this.intrinsicState = intrinsicState;
}
operation(extrinsicState) {
return `Intrinsic: ${this.intrinsicState}, Extrinsic: ${extrinsicState}`;
}
}
// 使用示例
const factory = new FlyweightFactory();
const flyweight1 = factory.getFlyweight('shared');
const flyweight2 = factory.getFlyweight('shared');
console.log(flyweight1 === flyweight2); // true
console.log(factory.getCount()); // 1
12. 代理模式(Proxy Pattern)
应用场景:访问控制、延迟加载、缓存、日志记录
class RealSubject {
request() {
return 'RealSubject: Handling request';
}
}
class Proxy {
constructor(realSubject) {
this.realSubject = realSubject;
}
request() {
if (this.checkAccess()) {
const result = this.realSubject.request();
this.logAccess();
return result;
}
return 'Proxy: Access denied';
}
checkAccess() {
console.log('Proxy: Checking access');
return true;
}
logAccess() {
console.log('Proxy: Logging the time of request');
}
}
// 使用示例
const realSubject = new RealSubject();
const proxy = new Proxy(realSubject);
console.log(proxy.request());
三、行为型设计模式详解
13. 责任链模式(Chain of Responsibility)
应用场景:请求处理管道、中间件、事件冒泡
class Handler {
setNext(handler) {
this.nextHandler = handler;
return handler;
}
handle(request) {
if (this.nextHandler) {
return this.nextHandler.handle(request);
}
return null;
}
}
class ConcreteHandler1 extends Handler {
handle(request) {
if (request === 'request1') {
return `Handler1: Processing ${request}`;
}
return super.handle(request);
}
}
class ConcreteHandler2 extends Handler {
handle(request) {
if (request === 'request2') {
return `Handler2: Processing ${request}`;
}
return super.handle(request);
}
}
class ConcreteHandler3 extends Handler {
handle(request) {
if (request === 'request3') {
return `Handler3: Processing ${request}`;
}
return super.handle(request);
}
}
// 使用示例
const handler1 = new ConcreteHandler1();
const handler2 = new ConcreteHandler2();
const handler3 = new ConcreteHandler3();
handler1.setNext(handler2).setNext(handler3);
console.log(handler1.handle('request2')); // Handler2: Processing request2
14. 命令模式(Command Pattern)
应用场景:任务队列、撤销/重做、宏命令
class Receiver {
action() {
console.log('Receiver: Performing action');
}
}
class Command {
constructor(receiver) {
this.receiver = receiver;
}
execute() {}
}
class ConcreteCommand extends Command {
execute() {
this.receiver.action();
}
}
class Invoker {
setCommand(command) {
this.command = command;
}
executeCommand() {
if (this.command) {
this.command.execute();
}
}
}
// 使用示例
const receiver = new Receiver();
const command = new ConcreteCommand(receiver);
const invoker = new Invoker();
invoker.setCommand(command);
invoker.executeCommand(); // Receiver: Performing action
15. 解释器模式(Interpreter Pattern)
应用场景:领域特定语言、语法解析、规则引擎
class Context {
constructor(input) {
this.input = input;
this.output = 0;
}
}
class Expression {
interpret(context) {}
}
class NumberExpression extends Expression {
constructor(number) {
super();
this.number = number;
}
interpret(context) {
context.output = this.number;
}
}
class PlusExpression extends Expression {
constructor(left, right) {
super();
this.left = left;
this.right = right;
}
interpret(context) {
this.left.interpret(context);
const leftResult = context.output;
this.right.interpret(context);
context.output += leftResult;
}
}
// 使用示例
const context = new Context();
const expression = new PlusExpression(
new NumberExpression(1),
new NumberExpression(2)
);
expression.interpret(context);
console.log(context.output); // 3
16. 迭代器模式(Iterator Pattern)
应用场景:集合遍历、惰性求值、分页处理
class Iterator {
constructor(collection) {
this.collection = collection;
this.index = 0;
}
hasNext() {
return this.index < this.collection.length;
}
next() {
return this.collection[this.index++];
}
}
class Collection {
constructor() {
this.items = [];
}
addItem(item) {
this.items.push(item);
}
getIterator() {
return new Iterator(this.items);
}
}
// 使用示例
const collection = new Collection();
collection.addItem('Item 1');
collection.addItem('Item 2');
collection.addItem('Item 3');
const iterator = collection.getIterator();
while (iterator.hasNext()) {
console.log(iterator.next());
}
17. 中介者模式(Mediator Pattern)
应用场景:组件通信、事件总线、聊天系统
class Mediator {
constructor() {
this.components = new Set();
}
register(component) {
this.components.add(component);
component.setMediator(this);
}
notify(sender, event) {
for (const component of this.components) {
if (component !== sender) {
component.receive(event);
}
}
}
}
class Component {
setMediator(mediator) {
this.mediator = mediator;
}
send(event) {
this.mediator.notify(this, event);
}
receive(event) {}
}
class ConcreteComponent extends Component {
constructor(name) {
super();
this.name = name;
}
receive(event) {
console.log(`${this.name} received: ${event}`);
}
}
// 使用示例
const mediator = new Mediator();
const comp1 = new ConcreteComponent('Component1');
const comp2 = new ConcreteComponent('Component2');
const comp3 = new ConcreteComponent('Component3');
mediator.register(comp1);
mediator.register(comp2);
mediator.register(comp3);
comp1.send('Hello from Component1');
18. 备忘录模式(Memento Pattern)
应用场景:撤销操作、状态保存、快照功能
class Memento {
constructor(state) {
this.state = state;
}
getState() {
return this.state;
}
}
class Originator {
constructor() {
this.state = '';
}
setState(state) {
this.state = state;
}
getState() {
return this.state;
}
saveStateToMemento() {
return new Memento(this.state);
}
getStateFromMemento(memento) {
this.state = memento.getState();
}
}
class Caretaker {
constructor() {
this.mementos = [];
}
add(memento) {
this.mementos.push(memento);
}
get(index) {
return this.mementos[index];
}
}
// 使用示例
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');
caretaker.add(originator.saveStateToMemento());
// 恢复到第二个状态
originator.getStateFromMemento(caretaker.get(1));
console.log(originator.getState()); // State #2
19. 观察者模式(Observer Pattern)
应用场景:事件处理、数据绑定、发布订阅
class Subject {
constructor() {
this.observers = [];
}
addObserver(observer) {
this.observers.push(observer);
}
removeObserver(observer) {
const index = this.observers.indexOf(observer);
if (index !== -1) {
this.observers.splice(index, 1);
}
}
notifyObservers(data) {
for (const observer of this.observers) {
observer.update(data);
}
}
}
class Observer {
update(data) {}
}
class ConcreteObserver extends Observer {
constructor(name) {
super();
this.name = name;
}
update(data) {
console.log(`${this.name} received: ${data}`);
}
}
// 使用示例
const subject = new Subject();
const observer1 = new ConcreteObserver('Observer1');
const observer2 = new ConcreteObserver('Observer2');
subject.addObserver(observer1);
subject.addObserver(observer2);
subject.notifyObservers('Hello Observers!');
20. 状态模式(State Pattern)
应用场景:状态机、游戏角色状态、工作流
class Context {
constructor(state) {
this.setState(state);
}
setState(state) {
this.state = state;
this.state.setContext(this);
}
request() {
this.state.handle();
}
}
class State {
setContext(context) {
this.context = context;
}
handle() {}
}
class ConcreteStateA extends State {
handle() {
console.log('State A handling request');
this.context.setState(new ConcreteStateB());
}
}
class ConcreteStateB extends State {
handle() {
console.log('State B handling request');
this.context.setState(new ConcreteStateA());
}
}
// 使用示例
const context = new Context(new ConcreteStateA());
context.request(); // State A handling request
context.request(); // State B handling request
context.request(); // State A handling request
21. 策略模式(Strategy Pattern)
应用场景:算法选择、支付方式、排序策略
class Strategy {
execute(a, b) {}
}
class AddStrategy extends Strategy {
execute(a, b) {
return a + b;
}
}
class SubtractStrategy extends Strategy {
execute(a, b) {
return a - b;
}
}
class MultiplyStrategy extends Strategy {
execute(a, b) {
return a * b;
}
}
class Context {
constructor(strategy) {
this.strategy = strategy;
}
setStrategy(strategy) {
this.strategy = strategy;
}
executeStrategy(a, b) {
return this.strategy.execute(a, b);
}
}
// 使用示例
const context = new Context(new AddStrategy());
console.log(context.executeStrategy(5, 3)); // 8
context.setStrategy(new SubtractStrategy());
console.log(context.executeStrategy(5, 3)); // 2
context.setStrategy(new MultiplyStrategy());
console.log(context.executeStrategy(5, 3)); // 15
22. 模板方法模式(Template Method Pattern)
应用场景:算法框架、工作流定义、钩子函数
class AbstractClass {
templateMethod() {
this.baseOperation1();
this.requiredOperation1();
this.baseOperation2();
this.hook1();
this.requiredOperation2();
this.baseOperation3();
this.hook2();
}
baseOperation1() {
console.log('AbstractClass: baseOperation1');
}
baseOperation2() {
console.log('AbstractClass: baseOperation2');
}
baseOperation3() {
console.log('AbstractClass: baseOperation3');
}
requiredOperation1() {}
requiredOperation2() {}
hook1() {}
hook2() {}
}
class ConcreteClass1 extends AbstractClass {
requiredOperation1() {
console.log('ConcreteClass1: requiredOperation1');
}
requiredOperation2() {
console.log('ConcreteClass1: requiredOperation2');
}
}
class ConcreteClass2 extends AbstractClass {
requiredOperation1() {
console.log('ConcreteClass2: requiredOperation1');
}
requiredOperation2() {
console.log('ConcreteClass2: requiredOperation2');
}
hook1() {
console.log('ConcreteClass2: hook1');
}
}
// 使用示例
const concrete1 = new ConcreteClass1();
concrete1.templateMethod();
console.log('');
const concrete2 = new ConcreteClass2();
concrete2.templateMethod();
23. 访问者模式(Visitor Pattern)
应用场景:数据操作、报表生成、编译器
class Visitor {
visitConcreteElementA(element) {}
visitConcreteElementB(element) {}
}
class ConcreteVisitor1 extends Visitor {
visitConcreteElementA(element) {
console.log('Visitor1: Visiting ConcreteElementA');
}
visitConcreteElementB(element) {
console.log('Visitor1: Visiting ConcreteElementB');
}
}
class ConcreteVisitor2 extends Visitor {
visitConcreteElementA(element) {
console.log('Visitor2: Visiting ConcreteElementA');
}
visitConcreteElementB(element) {
console.log('Visitor2: Visiting ConcreteElementB');
}
}
class Element {
accept(visitor) {}
}
class ConcreteElementA extends Element {
accept(visitor) {
visitor.visitConcreteElementA(this);
}
operationA() {
return 'ConcreteElementA operation';
}
}
class ConcreteElementB extends Element {
accept(visitor) {
visitor.visitConcreteElementB(this);
}
operationB() {
return 'ConcreteElementB operation';
}
}
// 使用示例
const elements = [new ConcreteElementA(), new ConcreteElementB()];
const visitor1 = new ConcreteVisitor1();
const visitor2 = new ConcreteVisitor2();
for (const element of elements) {
element.accept(visitor1);
}
for (const element of elements) {
element.accept(visitor2);
}
四、设计模式选择指南
何时使用何种模式?
| 场景 | 推荐模式 | 说明 |
|---|---|---|
| 对象创建复杂 | 建造者模式 | 当对象有很多可选参数时 |
| 需要全局唯一实例 | 单例模式 | 配置对象、日志记录器等 |
| 接口不兼容 | 适配器模式 | 集成第三方库或遗留代码 |
| 需要动态添加功能 | 装饰器模式 | 功能扩展而不修改原有代码 |
| 组件间通信复杂 | 中介者模式 | 减少组件间的直接依赖 |
| 需要状态管理 | 状态模式 | 对象行为随状态改变 |
| 算法选择灵活 | 策略模式 | 运行时选择不同算法 |
设计模式最佳实践
- 不要过度设计:只在真正需要时使用设计模式
- 保持简单:优先选择简单的解决方案
- 遵循SOLID原则:确保代码的可维护性和扩展性
- 考虑性能影响:某些模式可能带来性能开销
- 团队共识:确保团队成员理解所使用的模式
五、现代JavaScript中的设计模式应用
ES6+ 特性与设计模式
// 使用Symbol实现单例模式
const Singleton = (() => {
const instance = Symbol('instance');
class Singleton {
constructor() {
if (!Singleton[instance]) {
Singleton[instance] = this;
}
return Singleton[instance];
}
}
return Singleton;
})();
// 使用Proxy实现装饰器模式
function createLoggingProxy(target) {
return new Proxy(target, {
get(obj, prop) {
console.log(`Getting property: ${prop}`);
return obj[prop];
},
set(obj, prop, value) {
console.log(`Setting property: ${prop} = ${value}`);
obj[prop] = value;
return true;
}
});
}
TypeScript中的设计模式
// 使用泛型实现工厂模式
interface Product {
operation(): string;
}
class ConcreteProductA implements Product {
operation(): string {
return 'ConcreteProductA';
}
}
class ConcreteProductB implements Product {
operation(): string {
return 'ConcreteProductB';
}
}
class Creator {
public createProduct<T extends Product>(type: new () => T): T {
return new type();
}
}
// 使用示例
const creator = new Creator();
const productA = creator.createProduct(ConcreteProductA);
console.log(productA.operation()); // ConcreteProductA
六、实战案例:电商系统设计模式应用
购物车系统实现
// 策略模式:不同的折扣策略
class DiscountStrategy {
calculate(amount) {}
}
class NoDiscount extends DiscountStrategy {
calculate(amount) {
return amount;
}
}
class PercentageDiscount extends DiscountStrategy {
constructor(percentage) {
super();
this.percentage = percentage;
}
calculate(amount) {
return amount * (1 - this.percentage / 100);
}
}
class FixedDiscount extends DiscountStrategy {
constructor(discount) {
super();
this.discount = discount;
}
calculate(amount) {
return Math.max(0, amount - this.discount);
}
}
// 观察者模式:库存通知
class Inventory {
constructor() {
this.observers = [];
this.stock = {};
}
addObserver(observer) {
this.observers.push(observer);
}
setStock(productId, quantity) {
this.stock[productId] = quantity;
this.notifyObservers(productId, quantity);
}
notifyObservers(productId, quantity) {
for (const observer of this.observers) {
observer.update(productId, quantity);
}
}
}
class StockObserver {
update(productId, quantity) {
if (quantity === 0) {
console.log(`Product ${productId} is out of stock!`);
} else if (quantity < 10) {
console.log(`Product ${productId} is running low: ${quantity} left`);
}
}
}
总结
设计模式是JavaScript开发中的重要工具,它们提供了经过验证的解决方案来处理常见的软件设计问题。通过掌握这23种设计模式,你能够:
- ✅ 编写更加可维护和可扩展的代码
- ✅ 提高代码的重用性和灵活性
- ✅ 更好地应对需求变化和系统演进
- ✅ 与团队成员建立共同的设计语言
记住,设计模式不是银弹,而是需要根据具体场景灵活运用的工具。在实际开发中,要结合项目的具体需求和团队的实际情况,选择最适合的设计模式。
关键收获:
- 创建型模式关注对象创建
- 结构型模式关注对象组合
- 行为型模式关注对象交互
- 每种模式都有其适用场景和优缺点
- 现代JavaScript特性让模式实现更加简洁
通过不断实践和反思,你将能够熟练运用这些设计模式,构建出更加健壮和优雅的JavaScript应用程序。
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考



