前端设计模式详解

前端设计模式全面解析

一、设计模式概述

1.1 什么是设计模式

设计模式是针对特定上下文的常见问题的可重用解决方案。在前端开发中,它们帮助我们构建可维护、可扩展、可重用的代码。

1.2 设计模式分类

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

二、创建型模式

2.1 工厂模式(Factory Pattern)

将对象创建逻辑封装起来。

javascript 复制代码
// 简单工厂
class ButtonFactory {
  createButton(type) {
    switch(type) {
      case 'primary':
        return new PrimaryButton();
      case 'secondary':
        return new SecondaryButton();
      default:
        throw new Error('Unknown button type');
    }
  }
}

// 工厂方法
class Dialog {
  createButton() {} // 抽象方法
  
  render() {
    const button = this.createButton();
    button.render();
  }
}

class WindowsDialog extends Dialog {
  createButton() {
    return new WindowsButton();
  }
}

class WebDialog extends Dialog {
  createButton() {
    return new WebButton();
  }
}

2.2 建造者模式(Builder Pattern)

分步骤构建复杂对象。

javascript 复制代码
class Car {
  constructor() {
    this.engine = null;
    this.seats = 0;
    this.gps = false;
  }
  
  toString() {
    return `Car with ${this.engine} engine, ${this.seats} seats, GPS: ${this.gps}`;
  }
}

class CarBuilder {
  constructor() {
    this.car = new Car();
  }
  
  setEngine(engine) {
    this.car.engine = engine;
    return this;
  }
  
  setSeats(seats) {
    this.car.seats = seats;
    return this;
  }
  
  setGPS(hasGPS) {
    this.car.gps = hasGPS;
    return this;
  }
  
  build() {
    return this.car;
  }
}

// 使用
const car = new CarBuilder()
  .setEngine('V8')
  .setSeats(4)
  .setGPS(true)
  .build();

console.log(car.toString());

2.3 单例模式(Singleton Pattern)

确保一个类只有一个实例。

javascript 复制代码
class Singleton {
  static #instance = null;
  
  constructor() {
    if (Singleton.#instance) {
      return Singleton.#instance;
    }
    Singleton.#instance = this;
    
    // 初始化代码
    this.config = {};
  }
  
  static getInstance() {
    if (!Singleton.#instance) {
      Singleton.#instance = new Singleton();
    }
    return Singleton.#instance;
  }
  
  setConfig(key, value) {
    this.config[key] = value;
  }
  
  getConfig(key) {
    return this.config[key];
  }
}

// 使用
const instance1 = Singleton.getInstance();
const instance2 = Singleton.getInstance();
console.log(instance1 === instance2); // true

2.4 原型模式(Prototype Pattern)

通过克隆现有对象创建新对象。

javascript 复制代码
class ComponentPrototype {
  constructor(name, styles = {}) {
    this.name = name;
    this.styles = styles;
    this.children = [];
  }
  
  clone() {
    const clone = new ComponentPrototype(this.name);
    clone.styles = { ...this.styles };
    clone.children = [...this.children];
    return clone;
  }
  
  addChild(child) {
    this.children.push(child);
  }
  
  render() {
    console.log(`Rendering ${this.name} with styles:`, this.styles);
  }
}

// 使用
const baseButton = new ComponentPrototype('Button', {
  color: 'blue',
  padding: '10px'
});

const primaryButton = baseButton.clone();
primaryButton.name = 'Primary Button';
primaryButton.styles.color = 'green';

const secondaryButton = baseButton.clone();
secondaryButton.styles.color = 'gray';

三、结构型模式

3.1 适配器模式(Adapter Pattern)

让不兼容的接口能够一起工作。

javascript 复制代码
// 旧系统
class OldPaymentSystem {
  processPayment(amountInDollars) {
    console.log(`Processing $${amountInDollars} payment`);
    return true;
  }
}

// 新系统(期望欧元)
class NewPaymentSystem {
  processPayment(amountInEuros) {
    console.log(`Processing €${amountInEuros} payment`);
    return true;
  }
}

// 适配器
class PaymentAdapter {
  constructor(oldSystem) {
    this.oldSystem = oldSystem;
  }
  
  processPayment(amountInEuros) {
    // 转换欧元为美元
    const amountInDollars = amountInEuros * 1.2;
    return this.oldSystem.processPayment(amountInDollars);
  }
}

// 使用
const oldSystem = new OldPaymentSystem();
const adapter = new PaymentAdapter(oldSystem);
adapter.processPayment(100); // 转换为 $120

3.2 装饰器模式(Decorator Pattern)

动态添加功能到对象。

javascript 复制代码
// 基础组件
class TextComponent {
  constructor(text) {
    this.text = text;
  }
  
  render() {
    return this.text;
  }
}

// 装饰器基类
class TextDecorator {
  constructor(component) {
    this.component = component;
  }
  
  render() {
    return this.component.render();
  }
}

// 具体装饰器
class BoldDecorator extends TextDecorator {
  render() {
    return `<b>${super.render()}</b>`;
  }
}

class ItalicDecorator extends TextDecorator {
  render() {
    return `<i>${super.render()}</i>`;
  }
}

class LinkDecorator extends TextDecorator {
  constructor(component, url) {
    super(component);
    this.url = url;
  }
  
  render() {
    return `<a href="${this.url}">${super.render()}</a>`;
  }
}

// 使用
let text = new TextComponent('Hello World');
text = new BoldDecorator(text);
text = new ItalicDecorator(text);
text = new LinkDecorator(text, 'https://example.com');

console.log(text.render());
// <a href="https://example.com"><i><b>Hello World</b></i></a>

3.3 代理模式(Proxy Pattern)

控制对对象的访问。

javascript 复制代码
// 真实对象
class ImageLoader {
  constructor(filename) {
    this.filename = filename;
    this.loadImage();
  }
  
  loadImage() {
    console.log(`Loading image: ${this.filename}`);
    // 模拟耗时的加载
    this.image = `Image data for ${this.filename}`;
  }
  
  display() {
    console.log(`Displaying: ${this.image}`);
  }
}

// 代理
class ImageProxy {
  constructor(filename) {
    this.filename = filename;
    this.realImage = null;
  }
  
  display() {
    if (!this.realImage) {
      this.realImage = new ImageLoader(this.filename);
    }
    this.realImage.display();
  }
}

// 使用
const image1 = new ImageProxy('photo1.jpg');
const image2 = new ImageProxy('photo2.jpg');

// 图片不会立即加载
image1.display(); // 加载并显示
image1.display(); // 直接显示(已缓存)
image2.display(); // 加载并显示

3.4 外观模式(Facade Pattern)

简化复杂系统的接口。

javascript 复制代码
// 复杂子系统
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 ${data} at ${position}`);
  }
}

class HardDrive {
  read(lba, size) {
    const data = `data from sector ${lba}`;
    console.log(`HardDrive read: ${data}`);
    return data;
  }
}

// 外观
class ComputerFacade {
  constructor() {
    this.cpu = new CPU();
    this.memory = new Memory();
    this.hardDrive = new HardDrive();
  }
  
  start() {
    console.log('Computer starting...');
    this.cpu.freeze();
    const bootData = this.hardDrive.read(0, 1024);
    this.memory.load(0x0, bootData);
    this.cpu.jump(0x0);
    this.cpu.execute();
    console.log('Computer started!');
  }
}

// 使用
const computer = new ComputerFacade();
computer.start();

3.5 组合模式(Composite Pattern)

以树形结构组合对象。

javascript 复制代码
// 组件接口
class UIComponent {
  constructor(name) {
    this.name = 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);
    }
  }
  
  render() {
    console.log(`Rendering ${this.name}`);
    this.children.forEach(child => child.render());
  }
}

// 叶子节点
class Button extends UIComponent {
  constructor(name) {
    super(name);
  }
  
  render() {
    console.log(`[Button] ${this.name}`);
  }
}

class Input extends UIComponent {
  constructor(name) {
    super(name);
  }
  
  render() {
    console.log(`[Input] ${this.name}`);
  }
}

// 使用
const form = new UIComponent('Login Form');
const usernameInput = new Input('Username');
const passwordInput = new Input('Password');
const submitButton = new Button('Submit');

form.add(usernameInput);
form.add(passwordInput);
form.add(submitButton);

const panel = new UIComponent('Main Panel');
panel.add(form);
panel.render();

四、行为型模式

4.1 观察者模式(Observer Pattern)

对象间的一对多依赖关系。

javascript 复制代码
// 观察者接口
class Observer {
  update(data) {}
}

// 主题
class Subject {
  constructor() {
    this.observers = [];
  }
  
  subscribe(observer) {
    this.observers.push(observer);
  }
  
  unsubscribe(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 UserInterface extends Observer {
  constructor(name) {
    super();
    this.name = name;
  }
  
  update(data) {
    console.log(`${this.name} received:`, data);
  }
}

// 使用
const newsPublisher = new Subject();

const ui1 = new UserInterface('Mobile App');
const ui2 = new UserInterface('Web Dashboard');
const ui3 = new UserInterface('Email Service');

newsPublisher.subscribe(ui1);
newsPublisher.subscribe(ui2);
newsPublisher.subscribe(ui3);

newsPublisher.notify('New product launched!');
newsPublisher.unsubscribe(ui2);
newsPublisher.notify('Special discount available!');

4.2 发布-订阅模式(Pub/Sub Pattern)

观察者模式的变体,使用消息通道。

javascript 复制代码
class EventBus {
  constructor() {
    this.events = {};
  }
  
  subscribe(event, callback) {
    if (!this.events[event]) {
      this.events[event] = [];
    }
    this.events[event].push(callback);
  }
  
  unsubscribe(event, callback) {
    if (!this.events[event]) return;
    this.events[event] = this.events[event].filter(cb => cb !== callback);
  }
  
  publish(event, data) {
    if (!this.events[event]) return;
    this.events[event].forEach(callback => callback(data));
  }
}

// 使用
const bus = new EventBus();

// 订阅者
const logger = data => console.log(`[LOG] ${data}`);
const notifier = data => console.log(`[NOTIFY] ${data}`);
const analyzer = data => console.log(`[ANALYZE] ${JSON.stringify(data)}`);

// 订阅事件
bus.subscribe('user.login', logger);
bus.subscribe('user.login', notifier);
bus.subscribe('user.purchase', analyzer);

// 发布事件
bus.publish('user.login', { username: 'john', time: new Date() });
bus.publish('user.purchase', { item: 'Book', price: 29.99 });

4.3 策略模式(Strategy Pattern)

定义一系列算法,使它们可以互换。

javascript 复制代码
// 策略接口
class PaymentStrategy {
  pay(amount) {}
}

// 具体策略
class CreditCardPayment extends PaymentStrategy {
  constructor(cardNumber, cvv) {
    super();
    this.cardNumber = cardNumber;
    this.cvv = cvv;
  }
  
  pay(amount) {
    console.log(`Paid $${amount} with credit card ${this.cardNumber}`);
  }
}

class PayPalPayment extends PaymentStrategy {
  constructor(email) {
    super();
    this.email = email;
  }
  
  pay(amount) {
    console.log(`Paid $${amount} with PayPal ${this.email}`);
  }
}

class CryptoPayment extends PaymentStrategy {
  constructor(walletAddress) {
    super();
    this.walletAddress = walletAddress;
  }
  
  pay(amount) {
    console.log(`Paid $${amount} with crypto to ${this.walletAddress}`);
  }
}

// 上下文
class ShoppingCart {
  constructor() {
    this.items = [];
    this.paymentStrategy = null;
  }
  
  addItem(item, price) {
    this.items.push({ item, price });
  }
  
  setPaymentStrategy(strategy) {
    this.paymentStrategy = strategy;
  }
  
  checkout() {
    const total = this.items.reduce((sum, item) => sum + item.price, 0);
    console.log(`Total: $${total}`);
    
    if (this.paymentStrategy) {
      this.paymentStrategy.pay(total);
      this.items = [];
    } else {
      throw new Error('Payment strategy not set');
    }
  }
}

// 使用
const cart = new ShoppingCart();
cart.addItem('Book', 25);
cart.addItem('Mouse', 40);

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

cart.addItem('Keyboard', 80);
cart.setPaymentStrategy(new PayPalPayment('john@example.com'));
cart.checkout();

4.4 状态模式(State Pattern)

对象内部状态改变时改变其行为。

javascript 复制代码
// 状态接口
class OrderState {
  constructor(order) {
    this.order = order;
  }
  
  next() {}
  previous() {}
  cancel() {}
}

// 具体状态
class PendingState extends OrderState {
  next() {
    this.order.setState(new ProcessingState(this.order));
    console.log('Order moved to processing');
  }
  
  cancel() {
    this.order.setState(new CancelledState(this.order));
    console.log('Order cancelled');
  }
}

class ProcessingState extends OrderState {
  next() {
    this.order.setState(new ShippedState(this.order));
    console.log('Order shipped');
  }
  
  previous() {
    this.order.setState(new PendingState(this.order));
    console.log('Order moved back to pending');
  }
}

class ShippedState extends OrderState {
  next() {
    this.order.setState(new DeliveredState(this.order));
    console.log('Order delivered');
  }
  
  previous() {
    this.order.setState(new ProcessingState(this.order));
    console.log('Order moved back to processing');
  }
}

class DeliveredState extends OrderState {
  // 最终状态
}

class CancelledState extends OrderState {
  // 最终状态
}

// 上下文
class Order {
  constructor() {
    this.state = new PendingState(this);
  }
  
  setState(state) {
    this.state = state;
  }
  
  next() {
    this.state.next();
  }
  
  previous() {
    this.state.previous();
  }
  
  cancel() {
    this.state.cancel();
  }
}

// 使用
const order = new Order();
order.next(); // Pending -> Processing
order.next(); // Processing -> Shipped
order.next(); // Shipped -> Delivered

const order2 = new Order();
order2.next(); // Pending -> Processing
order2.cancel(); // Processing -> Cancelled

4.5 命令模式(Command Pattern)

将请求封装为对象。

javascript 复制代码
// 命令接口
class Command {
  execute() {}
  undo() {}
}

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

class ThermostatUpCommand extends Command {
  constructor(thermostat) {
    super();
    this.thermostat = thermostat;
    this.previousTemp = 0;
  }
  
  execute() {
    this.previousTemp = this.thermostat.getTemperature();
    this.thermostat.setTemperature(this.previousTemp + 2);
  }
  
  undo() {
    this.thermostat.setTemperature(this.previousTemp);
  }
}

// 接收者
class Light {
  turnOn() {
    console.log('Light is ON');
  }
  
  turnOff() {
    console.log('Light is OFF');
  }
}

class Thermostat {
  constructor() {
    this.temperature = 20;
  }
  
  getTemperature() {
    return this.temperature;
  }
  
  setTemperature(temp) {
    this.temperature = temp;
    console.log(`Thermostat set to ${temp}°C`);
  }
}

// 调用者
class RemoteControl {
  constructor() {
    this.commands = [];
    this.history = [];
  }
  
  setCommand(command) {
    this.commands.push(command);
  }
  
  pressButton(index) {
    if (index < this.commands.length) {
      const command = this.commands[index];
      command.execute();
      this.history.push(command);
    }
  }
  
  pressUndo() {
    if (this.history.length > 0) {
      const command = this.history.pop();
      command.undo();
    }
  }
}

// 使用
const remote = new RemoteControl();
const light = new Light();
const thermostat = new Thermostat();

const lightOn = new LightOnCommand(light);
const tempUp = new ThermostatUpCommand(thermostat);

remote.setCommand(lightOn);
remote.setCommand(tempUp);

remote.pressButton(0); // Light on
remote.pressButton(1); // Temperature up
remote.pressUndo();    // Temperature down
remote.pressUndo();    // Light off

五、前端特定模式

5.1 模块模式(Module Pattern)

使用闭包创建私有作用域。

javascript 复制代码
const UserModule = (function() {
  // 私有变量
  let users = [];
  let userCount = 0;
  
  // 私有方法
  function generateId() {
    return Date.now().toString(36) + Math.random().toString(36).substr(2);
  }
  
  // 公共接口
  return {
    addUser(name, email) {
      const user = {
        id: generateId(),
        name,
        email,
        createdAt: new Date()
      };
      users.push(user);
      userCount++;
      return user.id;
    },
    
    getUser(id) {
      return users.find(user => user.id === id);
    },
    
    getAllUsers() {
      return [...users];
    },
    
    getUserCount() {
      return userCount;
    },
    
    // 仅返回公开数据
    getPublicUserData(id) {
      const user = this.getUser(id);
      if (user) {
        const { email, ...publicData } = user;
        return publicData;
      }
      return null;
    }
  };
})();

// 使用
const userId = UserModule.addUser('John', 'john@example.com');
console.log(UserModule.getPublicUserData(userId));

5.2 混入模式(Mixin Pattern)

通过组合扩展类功能。

javascript 复制代码
// Mixins
const Loggable = Base => class extends Base {
  log(message) {
    console.log(`[${this.constructor.name}] ${message}`);
  }
};

const Serializable = Base => class extends Base {
  serialize() {
    return JSON.stringify(this);
  }
  
  static deserialize(json) {
    const data = JSON.parse(json);
    return new this(data);
  }
};

const Validatable = Base => class extends Base {
  validate() {
    const errors = [];
    
    // 检查必需字段
    if (this.requiredFields) {
      this.requiredFields.forEach(field => {
        if (!this[field]) {
          errors.push(`${field} is required`);
        }
      });
    }
    
    return {
      isValid: errors.length === 0,
      errors
    };
  }
};

// 基础类
class Model {
  constructor(data = {}) {
    Object.assign(this, data);
  }
  
  save() {
    console.log('Saving model...');
  }
}

// 应用Mixins
class User extends Serializable(Validatable(Loggable(Model))) {
  constructor(data) {
    super(data);
    this.requiredFields = ['name', 'email'];
  }
}

// 使用
const user = new User({
  name: 'John Doe',
  email: 'john@example.com'
});

user.log('Created user');
console.log(user.validate());

const json = user.serialize();
const user2 = User.deserialize(json);

5.3 中间件模式(Middleware Pattern)

处理请求的管道。

javascript 复制代码
class MiddlewarePipeline {
  constructor() {
    this.middlewares = [];
  }
  
  use(middleware) {
    this.middlewares.push(middleware);
  }
  
  async execute(context, finalHandler) {
    let index = -1;
    
    const dispatch = async i => {
      if (i <= index) {
        throw new Error('next() called multiple times');
      }
      
      index = i;
      let fn = this.middlewares[i];
      
      if (i === this.middlewares.length) {
        fn = finalHandler;
      }
      
      if (!fn) {
        return;
      }
      
      await fn(context, () => dispatch(i + 1));
    };
    
    return dispatch(0);
  }
}

// 使用示例:HTTP请求处理
const pipeline = new MiddlewarePipeline();

// 中间件
pipeline.use(async (ctx, next) => {
  console.log('Middleware 1: Logging request');
  ctx.startTime = Date.now();
  await next();
  const duration = Date.now() - ctx.startTime;
  console.log(`Middleware 1: Request took ${duration}ms`);
});

pipeline.use(async (ctx, next) => {
  console.log('Middleware 2: Authentication');
  ctx.user = { id: 1, name: 'John' };
  await next();
});

pipeline.use(async (ctx, next) => {
  console.log('Middleware 3: Authorization');
  if (!ctx.user) {
    throw new Error('Unauthorized');
  }
  await next();
});

// 最终处理函数
async function finalHandler(ctx) {
  console.log('Final handler: Processing request');
  console.log('User:', ctx.user);
  ctx.response = { success: true, data: 'Some data' };
}

// 执行
const context = { request: { url: '/api/data' } };
pipeline.execute(context, finalHandler)
  .then(() => console.log('Response:', context.response))
  .catch(err => console.error('Error:', err.message));

5.4 组件模式(Component Pattern)

javascript 复制代码
// 基础组件类
class Component {
  constructor(props = {}) {
    this.props = props;
    this.state = {};
    this.children = [];
  }
  
  setState(newState) {
    this.state = { ...this.state, ...newState };
    this.render();
  }
  
  addChild(child) {
    this.children.push(child);
  }
  
  render() {
    throw new Error('render() must be implemented');
  }
  
  mount(container) {
    this.container = container;
    this.render();
  }
}

// 具体组件
class Button extends Component {
  constructor(props) {
    super(props);
    this.state = { clicked: false };
  }
  
  handleClick = () => {
    this.setState({ clicked: true });
    if (this.props.onClick) {
      this.props.onClick();
    }
  };
  
  render() {
    const button = document.createElement('button');
    button.textContent = this.props.label || 'Click me';
    button.style.backgroundColor = this.state.clicked ? 'green' : 'blue';
    button.style.color = 'white';
    button.style.padding = '10px 20px';
    button.onclick = this.handleClick;
    
    if (this.container) {
      this.container.innerHTML = '';
      this.container.appendChild(button);
    }
    
    return button;
  }
}

class Form extends Component {
  render() {
    const form = document.createElement('form');
    form.style.padding = '20px';
    form.style.border = '1px solid #ccc';
    
    this.children.forEach(child => {
      const element = child.render();
      form.appendChild(element);
    });
    
    if (this.container) {
      this.container.innerHTML = '';
      this.container.appendChild(form);
    }
    
    return form;
  }
}

// 使用
const submitButton = new Button({
  label: 'Submit',
  onClick: () => console.log('Submitted!')
});

const cancelButton = new Button({
  label: 'Cancel',
  onClick: () => console.log('Cancelled!')
});

const form = new Form();
form.addChild(submitButton);
form.addChild(cancelButton);

// 挂载到DOM
form.mount(document.getElementById('app'));

六、React/Vue中的设计模式

6.1 高阶组件(HOC)- React

jsx 复制代码
// 高阶组件
const withLoading = (WrappedComponent) => {
  return function WithLoadingComponent({ isLoading, ...props }) {
    if (isLoading) {
      return <div className="loading">Loading...</div>;
    }
    return <WrappedComponent {...props} />;
  };
};

const withError = (WrappedComponent) => {
  return function WithErrorComponent({ error, ...props }) {
    if (error) {
      return <div className="error">Error: {error.message}</div>;
    }
    return <WrappedComponent {...props} />;
  };
};

// 使用
const DataDisplay = ({ data }) => (
  <div className="data">{JSON.stringify(data)}</div>
);

const EnhancedDataDisplay = withError(withLoading(DataDisplay));

// 使用示例
<EnhancedDataDisplay
  isLoading={loading}
  error={error}
  data={data}
/>

6.2 渲染属性(Render Props)- React

jsx 复制代码
class MouseTracker extends React.Component {
  state = { x: 0, y: 0 };
  
  handleMouseMove = (event) => {
    this.setState({
      x: event.clientX,
      y: event.clientY
    });
  };
  
  render() {
    return (
      <div style={{ height: '100vh' }} onMouseMove={this.handleMouseMove}>
        {this.props.render(this.state)}
      </div>
    );
  }
}

// 使用
<MouseTracker render={({ x, y }) => (
  <h1>The mouse position is ({x}, {y})</h1>
)} />

6.3 提供者模式(Provider Pattern)

javascript 复制代码
// React Context
const ThemeContext = React.createContext();

class ThemeProvider extends React.Component {
  state = { theme: 'light' };
  
  toggleTheme = () => {
    this.setState(prev => ({
      theme: prev.theme === 'light' ? 'dark' : 'light'
    }));
  };
  
  render() {
    return (
      <ThemeContext.Provider value={{
        theme: this.state.theme,
        toggleTheme: this.toggleTheme
      }}>
        {this.props.children}
      </ThemeContext.Provider>
    );
  }
}

// 消费
const ThemedButton = () => (
  <ThemeContext.Consumer>
    {({ theme, toggleTheme }) => (
      <button 
        style={{
          backgroundColor: theme === 'dark' ? '#333' : '#fff',
          color: theme === 'dark' ? '#fff' : '#333'
        }}
        onClick={toggleTheme}
      >
        Toggle Theme
      </button>
    )}
  </ThemeContext.Consumer>
);

6.4 Vue组合式函数(Composables)

javascript 复制代码
// useMouse.js - Vue 3 Composition API
import { ref, onMounted, onUnmounted } from 'vue';

export function useMouse() {
  const x = ref(0);
  const y = ref(0);
  
  const update = event => {
    x.value = event.pageX;
    y.value = event.pageY;
  };
  
  onMounted(() => window.addEventListener('mousemove', update));
  onUnmounted(() => window.removeEventListener('mousemove', update));
  
  return { x, y };
}

// useFetch.js
import { ref } from 'vue';

export function useFetch(url) {
  const data = ref(null);
  const error = ref(null);
  const loading = ref(false);
  
  const fetchData = async () => {
    loading.value = true;
    try {
      const response = await fetch(url);
      data.value = await response.json();
    } catch (err) {
      error.value = err;
    } finally {
      loading.value = false;
    }
  };
  
  fetchData();
  
  return { data, error, loading, refetch: fetchData };
}

七、设计模式选择指南

模式 适用场景 优点 缺点
工厂模式 需要创建多种类似对象 封装创建逻辑,易于扩展 增加系统复杂度
单例模式 全局唯一实例(配置、日志) 节省内存,全局访问 测试困难,全局状态污染
观察者模式 一对多依赖关系 松耦合,易于扩展 可能引起内存泄漏
装饰器模式 动态添加功能 灵活,符合开放封闭原则 多层装饰复杂
策略模式 多种算法切换 避免条件语句,易于扩展 增加策略类数量
中间件模式 处理请求管道 关注点分离,易于测试 可能影响性能

八、最佳实践

  1. 不要过度设计:简单的代码比复杂的设计模式更好
  2. 模式组合使用:实际项目中经常组合多种模式
  3. 考虑可测试性:设计模式应提高代码的可测试性
  4. 保持一致性:团队内统一使用某些模式
  5. 文档化:对使用的设计模式进行文档说明

九、现代JavaScript中的新特性

9.1 Proxy和Reflect实现模式

javascript 复制代码
// 使用Proxy实现数据绑定
function createObservable(obj, callback) {
  return new Proxy(obj, {
    set(target, property, value) {
      const oldValue = target[property];
      target[property] = value;
      callback(property, oldValue, value);
      return true;
    },
    
    get(target, property) {
      console.log(`Getting ${property}`);
      return target[property];
    }
  });
}

const user = createObservable(
  { name: 'John', age: 30 },
  (prop, oldVal, newVal) => {
    console.log(`${prop} changed from ${oldVal} to ${newVal}`);
  }
);

user.name = 'Jane'; // 触发回调

9.2 使用ES6+特性简化模式

javascript 复制代码
// 使用Symbol实现私有属性
const _private = Symbol('private');

class MyClass {
  constructor() {
    this[_private] = 'secret';
  }
  
  getSecret() {
    return this[_private];
  }
}

// 使用Generator实现迭代器模式
function* paginate(items, pageSize) {
  for (let i = 0; i < items.length; i += pageSize) {
    yield items.slice(i, i + pageSize);
  }
}

const items = [1, 2, 3, 4, 5, 6, 7, 8, 9];
for (const page of paginate(items, 3)) {
  console.log('Page:', page);
}

设计模式是解决常见问题的工具箱,理解它们有助于编写更优雅、可维护的代码。

相关推荐
IT_陈寒2 小时前
Java并发编程避坑指南:这5个隐藏陷阱让你的性能暴跌50%!
前端·人工智能·后端
ZouZou老师2 小时前
C++设计模式之责任链模式:以家具生产为例
c++·设计模式·责任链模式
jinxinyuuuus2 小时前
快手在线去水印:短链解析、API逆向与视频流的元数据重构
前端·人工智能·算法·重构
棒棒的唐2 小时前
avue uploader图片预览拉伸变型的css处理方法
前端·css
sunshine~~~2 小时前
ROS 2 Jazzy + Python 3.12 + Web 前端案例
开发语言·前端·python·anaconda·ros2
WYiQIU2 小时前
突破字节前端2-1⾯试: JS异步编程问题应答范式及进阶(视频教学及完整源码笔记)
开发语言·前端·javascript·vue.js·笔记·面试·github
quikai19812 小时前
python练习第四组
开发语言·前端·python
爱上妖精的尾巴2 小时前
5-40 WPS JS宏 综合实例应用-5(求字符串中的最大值记录)
开发语言·前端·javascript·wps·js宏·jsa
曹卫平dudu2 小时前
用Trea来快速生成一个浏览器插件
前端