JavaScript常用设计模式完整指南

引言

设计模式是软件工程中解决常见问题的可复用方案。在JavaScript开发中,合理运用设计模式可以提高代码的可维护性、可扩展性和可读性。本文将详细介绍JavaScript中常用的设计模式及其实现。

一、设计模式分类

设计模式主要分为三大类:

  • 创建型模式: 处理对象创建机制
  • 结构型模式: 处理对象组合和关系
  • 行为型模式: 处理对象间通信和职责分配

二、创建型模式

2.1 单例模式 (Singleton Pattern)

确保一个类只有一个实例, 并提供全局访问点。

javascript 复制代码
// ES6实现
class Singleton {
  constructor() {
    if (Singleton.instance) {
      return Singleton.instance;
    }
    this.data = {};
    Singleton.instance = this;
    return this;
  }

  setData(key, value) {
    this.data[key] = value;
  }

  getData(key) {
    return this.data[key];
  }
}

// 使用示例
const instance1 = new Singleton();
const instance2 = new Singleton();

console.log(instance1 === instance2); // true
instance1.setData('name', 'Singleton');
console.log(instance2.getData('name')); // 'Singleton'

// 闭包实现
const SingletonClosure = (function() {
  let instance;
  
  function createInstance() {
    const object = { data: {} };
    return {
      setData: (key, value) => object.data[key] = value,
      getData: (key) => object.data[key]
    };
  }
  
  return {
    getInstance: function() {
      if (!instance) {
        instance = createInstance();
      }
      return instance;
    }
  };
})();
2.2 工厂模式 (Factory Pattern)

创建对象而不暴露创建逻辑, 通过一个公共接口创建对象。

javascript 复制代码
// 简单工厂模式
class Car {
  constructor(options) {
    this.type = options.type || 'sedan';
    this.color = options.color || 'white';
    this.price = options.price || 20000;
  }
}

class Truck {
  constructor(options) {
    this.type = options.type || 'truck';
    this.color = options.color || 'blue';
    this.price = options.price || 50000;
    this.capacity = options.capacity || '5t';
  }
}

class VehicleFactory {
  static createVehicle(type, options) {
    switch (type) {
      case 'car':
        return new Car(options);
      case 'truck':
        return new Truck(options);
      default:
        throw new Error('Unknown vehicle type');
    }
  }
}

// 使用示例
const myCar = VehicleFactory.createVehicle('car', {
  color: 'red',
  price: 25000
});

const myTruck = VehicleFactory.createVehicle('truck', {
  color: 'black',
  capacity: '10t'
});

// 工厂方法模式
class Vehicle {
  drive() {
    console.log(`${this.type} is driving`);
  }
}

class Car2 extends Vehicle {
  constructor() {
    super();
    this.type = 'Car';
  }
}

class Truck2 extends Vehicle {
  constructor() {
    super();
    this.type = 'Truck';
  }
}

class VehicleFactory2 {
  createVehicle() {
    throw new Error('This method must be overridden');
  }
}

class CarFactory extends VehicleFactory2 {
  createVehicle() {
    return new Car2();
  }
}

class TruckFactory extends VehicleFactory2 {
  createVehicle() {
    return new Truck2();
  }
}
2.3 建造者模式 (Builder Pattern)

将复杂对象的构建与其表示分离, 使同样的构建过程可以创建不同的表示。

javascript 复制代码
class Pizza {
  constructor() {
    this.size = null;
    this.crust = null;
    this.cheese = false;
    this.pepperoni = false;
    this.mushrooms = false;
    this.onions = false;
  }

  describe() {
    console.log(`Pizza: Size-${this.size}, Crust-${this.crust}, 
      Cheese-${this.cheese}, Pepperoni-${this.pepperoni},
      Mushrooms-${this.mushrooms}, Onions-${this.onions}`);
  }
}

class PizzaBuilder {
  constructor() {
    this.pizza = new Pizza();
  }

  setSize(size) {
    this.pizza.size = size;
    return this;
  }

  setCrust(crust) {
    this.pizza.crust = crust;
    return this;
  }

  addCheese() {
    this.pizza.cheese = true;
    return this;
  }

  addPepperoni() {
    this.pizza.pepperoni = true;
    return this;
  }

  addMushrooms() {
    this.pizza.mushrooms = true;
    return this;
  }

  addOnions() {
    this.pizza.onions = true;
    return this;
  }

  build() {
    return this.pizza;
  }
}

// 使用示例
const pizza = new PizzaBuilder()
  .setSize('large')
  .setCrust('thin')
  .addCheese()
  .addPepperoni()
  .addMushrooms()
  .build();

pizza.describe();
2.4 原型模式 (Prototype Pattern)

通过复制现有对象来创建新对象, 而不是通过实例化类。

javascript 复制代码
// 使用Object.create实现原型模式
const carPrototype = {
  wheels: 4,
  drive() {
    console.log(`${this.brand} is driving with ${this.wheels} wheels`);
  },
  clone() {
    return Object.create(this);
  }
};

// 创建新对象
const tesla = Object.create(carPrototype);
tesla.brand = 'Tesla';
tesla.model = 'Model 3';

const anotherTesla = Object.create(tesla);
anotherTesla.model = 'Model S';

tesla.drive(); // Tesla is driving with 4 wheels
anotherTesla.drive(); // Tesla is driving with 4 wheels

// ES6类实现原型模式
class VehiclePrototype {
  constructor(proto) {
    Object.assign(this, proto);
  }

  clone() {
    return new VehiclePrototype(this);
  }
}

const bikeProto = {
  wheels: 2,
  ride() {
    console.log(`Riding ${this.brand} with ${this.wheels} wheels`);
  }
};

const bike = new VehiclePrototype(bikeProto);
bike.brand = 'Giant';
const anotherBike = bike.clone();
anotherBike.brand = 'Trek';

三、结构型模式

3.1 装饰器模式 (Decorator Pattern)

动态地给对象添加额外职责, 而不改变其结构。

javascript 复制代码
// ES7装饰器语法
function log(target, name, descriptor) {
  const original = descriptor.value;
  
  descriptor.value = function(...args) {
    console.log(`Calling ${name} with`, args);
    const result = original.apply(this, args);
    console.log(`Result: ${result}`);
    return result;
  };
  
  return descriptor;
}

class Calculator {
  @log
  add(a, b) {
    return a + b;
  }
}

// 传统JavaScript实现
class Coffee {
  cost() {
    return 5;
  }
}

class CoffeeDecorator {
  constructor(coffee) {
    this.coffee = coffee;
  }

  cost() {
    return this.coffee.cost();
  }
}

class MilkDecorator extends CoffeeDecorator {
  cost() {
    return this.coffee.cost() + 2;
  }
}

class SugarDecorator extends CoffeeDecorator {
  cost() {
    return this.coffee.cost() + 1;
  }
}

// 使用示例
let myCoffee = new Coffee();
console.log(`Basic coffee: $${myCoffee.cost()}`);

myCoffee = new MilkDecorator(myCoffee);
console.log(`Coffee with milk: $${myCoffee.cost()}`);

myCoffee = new SugarDecorator(myCoffee);
console.log(`Coffee with milk and sugar: $${myCoffee.cost()}`);
3.2 代理模式 (Proxy Pattern)

为其他对象提供一种代理以控制对这个对象的访问。

javascript 复制代码
// ES6 Proxy实现
const target = {
  message: "Hello, World!",
  getMessage() {
    return this.message;
  }
};

const handler = {
  get: function(obj, prop) {
    if (prop === 'message') {
      console.log('Accessing message property');
      return obj[prop] + ' (via proxy)';
    }
    return obj[prop];
  },
  
  set: function(obj, prop, value) {
    if (prop === 'message') {
      console.log(`Setting message to: ${value}`);
      obj[prop] = value;
      return true;
    }
    return false;
  }
};

const proxy = new Proxy(target, handler);

console.log(proxy.message); // "Hello, World! (via proxy)"
proxy.message = "New Message"; // "Setting message to: New Message"

// 保护代理示例
const sensitiveData = {
  username: 'admin',
  password: 'secret123',
  creditCard: '1234-5678-9012-3456'
};

const protectionHandler = {
  get: function(obj, prop) {
    if (prop === 'password' || prop === 'creditCard') {
      return 'Access denied';
    }
    return obj[prop];
  },
  
  set: function(obj, prop, value) {
    if (prop === 'password' || prop === 'creditCard') {
      console.log('Cannot modify sensitive data directly');
      return false;
    }
    obj[prop] = value;
    return true;
  }
};

const protectedData = new Proxy(sensitiveData, protectionHandler);
3.3 适配器模式 (Adapter Pattern)

将一个类的接口转换成客户期望的另一个接口。

javascript 复制代码
// 旧系统接口
class OldSystem {
  specificRequest() {
    return 'Old system response';
  }
}

// 新系统期望的接口
class NewSystem {
  request() {
    return 'New system response';
  }
}

// 适配器
class Adapter {
  constructor(oldSystem) {
    this.oldSystem = oldSystem;
  }

  request() {
    const result = this.oldSystem.specificRequest();
    return `Adapted: ${result}`;
  }
}

// 使用示例
const oldSystem = new OldSystem();
const adapter = new Adapter(oldSystem);

console.log(adapter.request()); // "Adapted: Old system response"

// 实际应用示例:数据格式适配
class JSONData {
  getData() {
    return '{"name": "John", "age": 30}';
  }
}

class XMLData {
  getData() {
    return '<user><name>John</name><age>30</age></user>';
  }
}

class DataAdapter {
  constructor(dataSource) {
    this.dataSource = dataSource;
  }

  getJSON() {
    const data = this.dataSource.getData();
    
    // 如果是XML,转换为JSON
    if (data.startsWith('<')) {
      // 简单转换逻辑
      const nameMatch = data.match(/<name>(.*?)<\/name>/);
      const ageMatch = data.match(/<age>(.*?)<\/age>/);
      
      return JSON.stringify({
        name: nameMatch ? nameMatch[1] : '',
        age: ageMatch ? parseInt(ageMatch[1]) : 0
      });
    }
    
    return data;
  }
}
3.4 外观模式 (Facade Pattern)

为复杂的子系统提供一个统一的简单接口。

javascript 复制代码
// 复杂的子系统
class CPU {
  start() {
    console.log('CPU started');
  }
  
  execute() {
    console.log('CPU executing instructions');
  }
}

class Memory {
  load() {
    console.log('Memory loading data');
  }
}

class HardDrive {
  read() {
    console.log('Hard drive reading data');
  }
}

// 外观
class ComputerFacade {
  constructor() {
    this.cpu = new CPU();
    this.memory = new Memory();
    this.hardDrive = new HardDrive();
  }

  startComputer() {
    console.log('Starting computer...');
    this.cpu.start();
    this.memory.load();
    this.hardDrive.read();
    this.cpu.execute();
    console.log('Computer started successfully');
  }
}

// 使用示例
const computer = new ComputerFacade();
computer.startComputer();

// 另一个例子:DOM操作外观
class DOMFacade {
  constructor(elementId) {
    this.element = document.getElementById(elementId);
  }

  setText(text) {
    this.element.textContent = text;
    return this;
  }

  setStyle(styles) {
    Object.assign(this.element.style, styles);
    return this;
  }

  addClass(className) {
    this.element.classList.add(className);
    return this;
  }

  on(event, handler) {
    this.element.addEventListener(event, handler);
    return this;
  }
}
3.5 组合模式 (Composite Pattern)

将对象组合成树形结构以表示'部分-整体'的层次结构。

javascript 复制代码
// 组件接口
class Component {
  constructor(name) {
    this.name = name;
  }

  add(component) {
    throw new Error('This method must be overridden');
  }

  remove(component) {
    throw new Error('This method must be overridden');
  }

  getChild(index) {
    throw new Error('This method must be overridden');
  }

  operation() {
    throw new Error('This method must be overridden');
  }
}

// 叶子节点
class Leaf extends Component {
  constructor(name) {
    super(name);
  }

  operation() {
    console.log(`Leaf ${this.name} operation`);
  }
}

// 复合节点
class Composite extends Component {
  constructor(name) {
    super(name);
    this.children = [];
  }

  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];
  }

  operation() {
    console.log(`Composite ${this.name} operation`);
    for (const child of this.children) {
      child.operation();
    }
  }
}

// 使用示例:文件系统
const root = new Composite('root');
const home = new Composite('home');
const user = new Composite('user');

const file1 = new Leaf('file1.txt');
const file2 = new Leaf('file2.txt');
const file3 = new Leaf('file3.txt');

root.add(home);
home.add(user);
user.add(file1);
user.add(file2);
root.add(file3);

root.operation();

四、行为型模式

4.1 策略模式 (Strategy Pattern)

定义一系列算法, 封装每个算法, 并使它们可以互相替换。

javascript 复制代码
// 策略接口
class PaymentStrategy {
  pay(amount) {
    throw new Error('This method must be overridden');
  }
}

// 具体策略
class CreditCardStrategy extends PaymentStrategy {
  constructor(cardNumber, cvv) {
    super();
    this.cardNumber = cardNumber;
    this.cvv = cvv;
  }

  pay(amount) {
    console.log(`Paid $${amount} using Credit Card ${this.cardNumber.slice(-4)}`);
    return true;
  }
}

class PayPalStrategy extends PaymentStrategy {
  constructor(email) {
    super();
    this.email = email;
  }

  pay(amount) {
    console.log(`Paid $${amount} using PayPal (${this.email})`);
    return true;
  }
}

class CryptoStrategy extends PaymentStrategy {
  constructor(walletAddress) {
    super();
    this.walletAddress = walletAddress;
  }

  pay(amount) {
    console.log(`Paid $${amount} using Crypto Wallet ${this.walletAddress.slice(0, 8)}...`);
    return true;
  }
}

// 上下文
class ShoppingCart {
  constructor() {
    this.items = [];
    this.paymentStrategy = null;
  }

  addItem(item, price) {
    this.items.push({ item, price });
  }

  calculateTotal() {
    return this.items.reduce((total, item) => total + item.price, 0);
  }

  setPaymentStrategy(strategy) {
    this.paymentStrategy = strategy;
  }

  checkout() {
    const total = this.calculateTotal();
    if (!this.paymentStrategy) {
      console.log('Please select a payment method');
      return false;
    }
    return this.paymentStrategy.pay(total);
  }
}

// 使用示例
const cart = new ShoppingCart();
cart.addItem('Book', 25);
cart.addItem('Headphones', 100);

cart.setPaymentStrategy(new CreditCardStrategy('1234-5678-9012-3456', '123'));
cart.checkout();

cart.setPaymentStrategy(new PayPalStrategy('user@example.com'));
cart.checkout();
4.2 观察者模式 (Observer Pattern / 发布-订阅模式)

定义对象间的一对多依赖关系, 当一个对象状态改变时, 所有依赖它的对象都会得到通知。

javascript 复制代码
// 发布-订阅实现
class EventEmitter {
  constructor() {
    this.events = {};
  }

  on(event, listener) {
    if (!this.events[event]) {
      this.events[event] = [];
    }
    this.events[event].push(listener);
    return () => this.off(event, listener);
  }

  off(event, listener) {
    if (!this.events[event]) return;
    
    const index = this.events[event].indexOf(listener);
    if (index > -1) {
      this.events[event].splice(index, 1);
    }
  }

  emit(event, ...args) {
    if (!this.events[event]) return;
    
    this.events[event].forEach(listener => {
      try {
        listener.apply(this, args);
      } catch (error) {
        console.error(`Error in event listener for ${event}:`, error);
      }
    });
  }

  once(event, listener) {
    const removeListener = this.on(event, (...args) => {
      listener.apply(this, args);
      removeListener();
    });
    return removeListener;
  }
}

// 使用示例
const emitter = new EventEmitter();

// 订阅事件
const unsubscribe = emitter.on('userLoggedIn', (user) => {
  console.log(`Welcome, ${user.name}!`);
});

emitter.on('userLoggedIn', (user) => {
  console.log(`Sending login notification to ${user.email}`);
});

// 发布事件
emitter.emit('userLoggedIn', { 
  name: 'John Doe', 
  email: 'john@example.com' 
});

// 取消订阅
unsubscribe();

// 观察者模式实现
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);
    }
  }

  notify(data) {
    this.observers.forEach(observer => observer.update(data));
  }
}

class Observer {
  constructor(name) {
    this.name = name;
  }

  update(data) {
    console.log(`${this.name} received:`, data);
  }
}
4.3 迭代器模式 (Iterator Pattern)

提供一种方法顺序访问聚合对象中的各个元素, 而又不暴露其内部表示。

javascript 复制代码
// 自定义迭代器
class Range {
  constructor(start, end, step = 1) {
    this.start = start;
    this.end = end;
    this.step = step;
  }

  [Symbol.iterator]() {
    let current = this.start;
    const end = this.end;
    const step = this.step;
    
    return {
      next() {
        if (current <= end) {
          const value = current;
          current += step;
          return { value, done: false };
        }
        return { done: true };
      }
    };
  }
}

// 使用示例
for (const num of new Range(1, 5)) {
  console.log(num); // 1, 2, 3, 4, 5
}

// 自定义集合迭代器
class Collection {
  constructor() {
    this.items = [];
  }

  add(item) {
    this.items.push(item);
  }

  [Symbol.iterator]() {
    let index = 0;
    const items = this.items;
    
    return {
      next() {
        if (index < items.length) {
          return { value: items[index++], done: false };
        }
        return { done: true };
      },
      
      return() {
        console.log('Iteration stopped prematurely');
        return { done: true };
      }
    };
  }

  // 生成器实现
  *filter(predicate) {
    for (const item of this.items) {
      if (predicate(item)) {
        yield item;
      }
    }
  }

  *map(transform) {
    for (const item of this.items) {
      yield transform(item);
    }
  }
}
4.4 命令模式 (Command Pattern)

将请求封装为对象, 从而允许参数化客户、队列请求、记录日志以及支持可撤销操作。

javascript 复制代码
// 命令接口
class Command {
  execute() {
    throw new Error('This method must be overridden');
  }

  undo() {
    throw new Error('This method must be overridden');
  }
}

// 具体命令
class LightOnCommand extends Command {
  constructor(light) {
    super();
    this.light = light;
  }

  execute() {
    this.light.turnOn();
  }

  undo() {
    this.light.turnOff();
  }
}

class LightOffCommand extends Command {
  constructor(light) {
    super();
    this.light = light;
  }

  execute() {
    this.light.turnOff();
  }

  undo() {
    this.light.turnOn();
  }
}

// 接收者
class Light {
  constructor(location) {
    this.location = location;
    this.isOn = false;
  }

  turnOn() {
    this.isOn = true;
    console.log(`${this.location} light is ON`);
  }

  turnOff() {
    this.isOn = false;
    console.log(`${this.location} light is OFF`);
  }
}

// 调用者
class RemoteControl {
  constructor() {
    this.commands = [];
    this.history = [];
  }

  setCommand(command) {
    this.commands.push(command);
  }

  executeCommands() {
    this.commands.forEach(command => {
      command.execute();
      this.history.push(command);
    });
    this.commands = [];
  }

  undoLast() {
    if (this.history.length > 0) {
      const lastCommand = this.history.pop();
      lastCommand.undo();
    }
  }
}

// 使用示例
const livingRoomLight = new Light('Living Room');
const kitchenLight = new Light('Kitchen');

const remote = new RemoteControl();

remote.setCommand(new LightOnCommand(livingRoomLight));
remote.setCommand(new LightOnCommand(kitchenLight));
remote.executeCommands();

remote.undoLast();

// 宏命令
class MacroCommand extends Command {
  constructor(commands) {
    super();
    this.commands = commands;
  }

  execute() {
    this.commands.forEach(command => command.execute());
  }

  undo() {
    // 逆序执行撤销
    this.commands.reverse().forEach(command => command.undo());
  }
}
4.5 状态模式 (State Pattern)

允许对象在其内部状态改变时改变其行为, 看起来像是修改了类。

javascript 复制代码
// 状态接口
class TrafficLightState {
  constructor(context) {
    this.context = context;
  }

  change() {
    throw new Error('This method must be overridden');
  }
}

// 具体状态
class RedLightState extends TrafficLightState {
  change() {
    console.log('Red light - STOP');
    this.context.setState(new GreenLightState(this.context));
  }
}

class GreenLightState extends TrafficLightState {
  change() {
    console.log('Green light - GO');
    this.context.setState(new YellowLightState(this.context));
  }
}

class YellowLightState extends TrafficLightState {
  change() {
    console.log('Yellow light - CAUTION');
    this.context.setState(new RedLightState(this.context));
  }
}

// 上下文
class TrafficLight {
  constructor() {
    this.state = new RedLightState(this);
  }

  setState(state) {
    this.state = state;
  }

  change() {
    this.state.change();
  }
}

// 使用示例
const trafficLight = new TrafficLight();

trafficLight.change(); // Red light - STOP
trafficLight.change(); // Green light - GO
trafficLight.change(); // Yellow light - CAUTION
trafficLight.change(); // Red light - STOP

// 更复杂的例子:文档编辑器状态
class Document {
  constructor() {
    this.state = new DraftState(this);
    this.content = '';
  }

  setState(state) {
    this.state = state;
  }

  write(text) {
    this.state.write(text);
  }

  publish() {
    this.state.publish();
  }
}

class DraftState {
  constructor(document) {
    this.document = document;
  }

  write(text) {
    this.document.content += text;
    console.log(`Draft: Added "${text}"`);
  }

  publish() {
    console.log('Publishing draft...');
    this.document.setState(new PublishedState(this.document));
  }
}

class PublishedState {
  constructor(document) {
    this.document = document;
  }

  write(text) {
    console.log('Cannot write to published document. Create new draft first.');
  }

  publish() {
    console.log('Document is already published.');
  }
}
4.6 职责链模式 (Chain of Responsibility Pattern)

使多个对象都有机会处理请求, 从而避免请求发送者和接收者之间的耦合关系。

javascript 复制代码
// 处理者接口
class Handler {
  constructor() {
    this.nextHandler = null;
  }

  setNext(handler) {
    this.nextHandler = handler;
    return handler;
  }

  handle(request) {
    if (this.nextHandler) {
      return this.nextHandler.handle(request);
    }
    console.log('No handler found for request:', request);
    return null;
  }
}

// 具体处理者
class AuthenticationHandler extends Handler {
  handle(request) {
    if (request.type === 'auth' && request.credentials === 'valid') {
      console.log('Authentication successful');
      return super.handle(request);
    } else if (request.type === 'auth') {
      console.log('Authentication failed');
      return null;
    }
    return super.handle(request);
  }
}

class AuthorizationHandler extends Handler {
  handle(request) {
    if (request.type === 'auth' && request.role === 'admin') {
      console.log('Authorization granted for admin');
      return super.handle(request);
    } else if (request.type === 'auth') {
      console.log('Authorization denied');
      return null;
    }
    return super.handle(request);
  }
}

class LoggingHandler extends Handler {
  handle(request) {
    console.log(`Logging request: ${JSON.stringify(request)}`);
    return super.handle(request);
  }
}

// 使用示例
const authHandler = new AuthenticationHandler();
const authzHandler = new AuthorizationHandler();
const logHandler = new LoggingHandler();

authHandler
  .setNext(authzHandler)
  .setNext(logHandler);

// 处理请求
const request1 = { type: 'auth', credentials: 'valid', role: 'admin' };
authHandler.handle(request1);

const request2 = { type: 'auth', credentials: 'invalid' };
authHandler.handle(request2);

// 实际应用:请求处理管道
class ValidationHandler extends Handler {
  handle(data) {
    if (!data.email || !data.email.includes('@')) {
      console.log('Validation failed: Invalid email');
      return null;
    }
    console.log('Validation passed');
    return super.handle(data);
  }
}

class SanitizationHandler extends Handler {
  handle(data) {
    data.email = data.email.trim().toLowerCase();
    console.log('Data sanitized');
    return super.handle(data);
  }
}

class SaveHandler extends Handler {
  handle(data) {
    console.log(`Saving data: ${data.email}`);
    return { success: true, id: Date.now() };
  }
}

五、其他重要模式

5.1 模块模式 (Module Pattern)
javascript 复制代码
// 使用IIFE实现模块模式
const UserModule = (function() {
  // 私有变量
  let users = [];
  let userCount = 0;

  // 私有方法
  function generateId() {
    return Date.now().toString(36) + Math.random().toString(36).substr(2);
  }

  // 公共接口
  return {
    addUser: function(name, email) {
      const user = {
        id: generateId(),
        name,
        email,
        createdAt: new Date()
      };
      users.push(user);
      userCount++;
      return user.id;
    },

    getUser: function(id) {
      return users.find(user => user.id === id);
    },

    getUsers: function() {
      return [...users]; // 返回副本
    },

    getUserCount: function() {
      return userCount;
    },

    removeUser: function(id) {
      const index = users.findIndex(user => user.id === id);
      if (index > -1) {
        users.splice(index, 1);
        userCount--;
        return true;
      }
      return false;
    }
  };
})();

// ES6模块语法
export class Calculator {
  static add(a, b) {
    return a + b;
  }

  static multiply(a, b) {
    return a * b;
  }
}
5.2 混入模式 (Mixin Pattern)
javascript 复制代码
// 混入函数
function mixin(target, ...sources) {
  Object.assign(target, ...sources);
  return target;
}

// 可复用的混入对象
const CanEat = {
  eat(food) {
    console.log(`${this.name} is eating ${food}`);
    this.energy += 10;
  }
};

const CanSleep = {
  sleep() {
    console.log(`${this.name} is sleeping`);
    this.energy += 20;
  }
};

const CanPlay = {
  play() {
    console.log(`${this.name} is playing`);
    this.energy -= 5;
  }
};

// 使用混入
class Animal {
  constructor(name) {
    this.name = name;
    this.energy = 100;
  }
}

class Dog extends Animal {
  constructor(name) {
    super(name);
    mixin(this, CanEat, CanSleep, CanPlay);
  }

  bark() {
    console.log(`${this.name} is barking!`);
  }
}

// 使用示例
const dog = new Dog('Rex');
dog.eat('bone');
dog.play();
dog.sleep();
dog.bark();

// ES6类混入
const Flyable = BaseClass => class extends BaseClass {
  fly() {
    console.log(`${this.name} is flying!`);
  }
};

class Bird extends Flyable(Animal) {
  constructor(name) {
    super(name);
  }
}

const bird = new Bird('Tweety');
bird.fly();
5.3 中介者模式 (Mediator Pattern)
javascript 复制代码
// 中介者
class ChatRoom {
  constructor() {
    this.users = new Map();
  }

  register(user) {
    this.users.set(user.name, user);
    user.chatRoom = this;
  }

  send(message, from, to) {
    if (to) {
      // 私聊
      const receiver = this.users.get(to);
      if (receiver) {
        receiver.receive(message, from);
      }
    } else {
      // 群聊
      this.users.forEach(user => {
        if (user.name !== from) {
          user.receive(message, from);
        }
      });
    }
  }
}

// 同事类
class User {
  constructor(name) {
    this.name = name;
    this.chatRoom = null;
  }

  send(message, to = null) {
    this.chatRoom.send(message, this.name, to);
  }

  receive(message, from) {
    console.log(`${from} to ${this.name}: ${message}`);
  }
}

// 使用示例
const chatRoom = new ChatRoom();

const alice = new User('Alice');
const bob = new User('Bob');
const charlie = new User('Charlie');

chatRoom.register(alice);
chatRoom.register(bob);
chatRoom.register(charlie);

alice.send('Hello everyone!');
bob.send('Hi Alice!', 'Alice');
charlie.send('Meeting at 3 PM', 'Alice');

六、总结与最佳实践

何时使用设计模式
  1. 单例模式: 全局配置、日志记录器、数据库连接池
  2. 工厂模式: 创建复杂对象、需要根据条件创建不同对象
  3. 观察者模式: 事件处理系统、实时数据更新
  4. 策略模式: 多种算法实现、需要动态切换行为
  5. 装饰器模式: 动态添加功能、AOP编程
JavaScript设计模式特点
  1. 灵活性: JavaScript的动态特性使得模式实现更加灵活
  2. 函数式特性: 可以利用高阶函数、闭包等特性简化模式实现
  3. 原型继承: 充分利用原型链实现继承和共享方法
  4. ES6+特性: 类语法、Proxy、Symbol、装饰器等增强了模式表达能力
最佳实践建议
  1. 不要过度设计: 只在必要时使用设计模式
  2. 保持简洁: JavaScript本身就很灵活,避免过度复杂的模式实现
  3. 结合语言特性: 充分利用JavaScript的函数式特性
  4. 考虑性能: 某些模式可能带来性能开销,在性能敏感场景要谨慎
  5. 团队共识: 确保团队成员理解所使用的设计模式

设计模式是解决特定问题的工具,而不是银弹。在实际开发中,应根据具体需求选择合适的模式,并灵活调整以适应JavaScript的语言特性。理解模式的核心思想比死记硬背实现方式更重要。

相关推荐
董世昌412 小时前
js怎样控制浏览器前进、后退、页面跳转?
开发语言·前端·javascript
走,带你去玩2 小时前
uniapp live-pusher + 腾讯云直播
前端·javascript·uni-app
徐同保2 小时前
electron打包项目
前端·javascript·electron
Maybyy2 小时前
如何在项目里面添加一个可以左右翻动并显示指定日期的日历
前端·vue.js
柯南二号2 小时前
【大前端】【Android】用 Python 脚本模拟点击 Android APP —— 全面技术指南
android·前端·python
Arvin_Rong2 小时前
前端动态 API 生成与封装:前端 API 调用的一种思路
前端
2401_860319522 小时前
DevUI组件库实战:从入门到企业级应用的深度探索,如何实现支持表格扩展和表格编辑功能
前端·前端框架
LYFlied2 小时前
从循环依赖检查插件Circular Dependency Plugin源码详解Webpack生命周期以及插件开发
前端·webpack·node.js·编译原理·plugin插件开发
麒qiqi3 小时前
【Linux 系统编程】文件 IO 与 Makefile 核心实战:从系统调用到工程编译
java·前端·spring