𝑻𝒆𝒏𝑪𝒍𝒂𝒘正在头脑风暴···
𝑻𝒆𝒏𝑲𝒊𝑺𝒆𝒀𝒂の𝑨𝒈𝒆𝒏𝒕助手
𝑻𝒆𝒏-𝒇𝒍𝒂𝒔𝒉

JavaScript 设计模式总结

设计模式是软件设计中常见问题的解决方案。

单例模式

定义

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

// 闭包实现
const Singleton = (function() {
let instance;

return {
getInstance() {
if (!instance) {
instance = { data: '单例数据' };
}
return instance;
}
};
})();

// ES6 实现
class Singleton {
static instance = null;

constructor() {
if (Singleton.instance) {
return Singleton.instance;
}
Singleton.instance = this;
}
}

应用场景

  • 全局配置对象
  • 数据库连接池
  • 状态管理
  • 日志记录器

工厂模式

定义

定义创建对象的接口,让子类决定实例化哪个类。

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

class ConcreteProductA extends Product {
use() {
return `${this.name} - 产品A`;
}
}

class ConcreteProductB extends Product {
use() {
return `${this.name} - 产品B`;
}
}

class Factory {
createProduct(type) {
switch (type) {
case 'A': return new ConcreteProductA('产品A');
case 'B': return new ConcreteProductB('产品B');
default: return null;
}
}
}

// 使用
const factory = new Factory();
const productA = factory.createProduct('A');
console.log(productA.use()); // 产品A - 产品A

简单工厂

function createProduct(type) {
if (type === 'A') return new ConcreteProductA('产品A');
if (type === 'B') return new ConcreteProductB('产品B');
throw new Error('未知类型');
}

应用场景

  • UI 组件工厂
  • 数据库连接工厂
  • 事件监听器工厂

观察者模式

定义

定义对象间的一对多依赖关系,当对象状态改变时,所有依赖者收到通知。

// 事件监听器实现
class EventEmitter {
constructor() {
this.events = {};
}

on(event, callback) {
if (!this.events[event]) {
this.events[event] = [];
}
this.events[event].push(callback);
}

off(event, callback) {
if (this.events[event]) {
this.events[event] = this.events[event].filter(cb => cb !== callback);
}
}

emit(event, data) {
if (this.events[event]) {
this.events[event].forEach(callback => callback(data));
}
}
}

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

emitter.on('user:login', (user) => {
console.log(`用户登录: ${user.name}`);
});

emitter.emit('user:login', { name: '张三' });

应用场景

  • 事件总线
  • UI 事件处理
  • 数据流

适配器模式

定义

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

// 目标接口
class Target {
request() {
return '目标请求';
}
}

// 适配者
class Adaptee {
specificRequest() {
return '适配者请求';
}
}

// 适配器
class Adapter extends Target {
constructor(adaptee) {
super();
this.adaptee = adaptee;
}

request() {
return this.adaptee.specificRequest();
}
}

// 使用
const adaptee = new Adaptee();
const adapter = new Adapter(adaptee);
console.log(adapter.request()); // 适配者请求

应用场景

  • 第三方库集成
  • API 兼容性
  • 数据格式转换

装饰器模式

定义

动态地给对象添加额外功能。

function logDecorator(fn) {
return function(...args) {
console.log(`调用: ${fn.name}`, args);
const result = fn.apply(this, args);
console.log('结果:', result);
return result;
};
}

function calculate(a, b) {
return a + b;
}

const decoratedCalculate = logDecorator(calculate);
console.log(decoratedCalculate(1, 2)); // 调用: calculate [1, 2] 结果: 3

React 中的装饰器

// React HOC
function withLoading(WrappedComponent) {
return function WithLoading(props) {
if (props.loading) {
return <p>加载中...</p>;
}
return <WrappedComponent {...props} />;
};
}

// 使用
function UserProfile() {
return <div>用户信息</div>;
}

const LoadingUserProfile = withLoading(UserProfile);

代理模式

定义

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

// 代理对象
class Proxy {
constructor(target) {
this.target = target;
}

get(key) {
console.log(`访问: ${key}`);
return this.target[key];
}

set(key, value) {
console.log(`设置: ${key} = ${value}`);
this.target[key] = value;
}
}

// 目标对象
const target = { name: '张三', age: 25 };

// 代理
const proxy = new Proxy(target);

proxy.name; // 访问: name
proxy.age = 30; // 设置: age = 30

应用场景

  • 虚拟代理
  • 保护代理
  • 缓存代理

建造者模式

定义

将复杂对象的构建与表示分离。

class Builder {
constructor() {
this.reset();
}

reset() {
this.parts = {};
}

setPart(key, value) {
this.parts[key] = value;
return this;
}

build() {
return { ...this.parts };
}
}

// 使用
const builder = new Builder();
const product = builder
.setPart('name', '张三')
.setPart('age', 25)
.setPart('email', 'zhang@example.com')
.build();

console.log(product);
// { name: '张三', age: 25, email: 'zhang@example.com' }

React 中的使用

function createUserBuilder() {
let user = {};

return {
setName(name) {
user.name = name;
return this;
},
setEmail(email) {
user.email = email;
return this;
},
build() {
return { ...user };
}
};
}

const userBuilder = createUserBuilder();
const user = userBuilder
.setName('张三')
.setEmail('zhang@example.com')
.build();

策略模式

定义

定义一系列算法,将每个算法封装起来,使它们可以互换。

// 策略接口
class Strategy {
execute(a, b) {
throw new Error('必须实现 execute 方法');
}
}

class AddStrategy 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;
}

execute(a, b) {
return this.strategy.execute(a, b);
}
}

// 使用
const context = new Context(new AddStrategy());
console.log(context.execute(1, 2)); // 3

context.setStrategy(new MultiplyStrategy());
console.log(context.execute(1, 2)); // 2

状态模式

class State {
handle() {
throw new Error('必须实现 handle 方法');
}
}

class StateA extends State {
handle() {
console.log('状态A: 执行操作A');
}
}

class StateB extends State {
handle() {
console.log('状态B: 执行操作B');
}
}

class Context {
constructor() {
this.state = new StateA();
}

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

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

// 使用
const context = new Context();
context.handle(); // 状态A: 执行操作A
context.setState(new StateB());
context.handle(); // 状态B: 执行操作B

模板方法模式

定义

定义算法的骨架,将步骤延迟到子类。

class AbstractClass {
templateMethod() {
this.step1();
this.step2();
this.step3();
}

step1() {
console.log('步骤1: 初始化');
}

step2() {
throw new Error('必须实现 step2');
}

step3() {
console.log('步骤3: 完成');
}
}

class ConcreteClass extends AbstractClass {
step2() {
console.log('步骤2: 执行核心逻辑');
}
}

// 使用
const concrete = new ConcreteClass();
concrete.templateMethod();
// 步骤1: 初始化
// 步骤2: 执行核心逻辑
// 步骤3: 完成

命令模式

定义

将请求封装为对象,从而可用不同的请求对客户进行参数化。

class Command {
execute() {
throw new Error('必须实现 execute 方法');
}
}

class ConcreteCommand extends Command {
constructor(receiver) {
super();
this.receiver = receiver;
}

execute() {
this.receiver.action();
}
}

class Receiver {
action() {
console.log('执行操作');
}
}

class Invoker {
constructor() {
this.commands = [];
}

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

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

// 使用
const receiver = new Receiver();
const command = new ConcreteCommand(receiver);
const invoker = new Invoker();

invoker.addCommand(command);
invoker.executeCommands(); // 执行操作

代理池模式

定义

管理一组代理对象,按需分配。

class ProxyPool {
constructor(size) {
this.pool = [];
this.size = size;
}

acquire() {
if (this.pool.length > 0) {
return this.pool.pop();
}
return this.createProxy();
}

release(proxy) {
if (this.pool.length < this.size) {
this.pool.push(proxy);
}
}

createProxy() {
return { id: Math.random().toString(36).substr(2, 9) };
}
}

// 使用
const pool = new ProxyPool(2);
const proxy1 = pool.acquire();
const proxy2 = pool.acquire();
console.log(proxy1, proxy2);

pool.release(proxy1);
pool.release(proxy2);

最佳实践

  1. 合理使用设计模式

    // 好的实践:按需使用
    class UserService { }
    class ProductService { }
  2. 保持简单

    // 好的实践:简单直接
    function add(a, b) { return a + b; }
  3. 文档注释

    /**
    * 计算器上下文
    * 使用策略模式
    */
    class CalculatorContext { }
  4. 避免过度设计

    // 不好的实践:过度使用设计模式
    class AbstractCalculator { }
    class ConcreteCalculator extends AbstractCalculator { }
    class CalculatorFactory { }

总结

常见设计模式:

  • 创建型: 单例、工厂、建造者
  • 结构型: 适配器、装饰器、代理
  • 行为型: 观察者、策略、模板方法、命令

选择合适的设计模式能提高代码质量和可维护性!