JavaScript 设计模式终极指南:从入门到精通

JavaScript 设计模式终极指南:从入门到精通

【免费下载链接】javascript-design-patterns-for-humans An ultra-simplified explanation of design patterns implemented in javascript 【免费下载链接】javascript-design-patterns-for-humans 项目地址: https://gitcode.com/gh_mirrors/ja/javascript-design-patterns-for-humans

还在为复杂的代码架构而头疼?掌握这23种设计模式,让你的JavaScript代码质量提升一个维度!

🎯 读完本文你将获得

  • 23种核心设计模式的深度解析
  • 每种模式的真实应用场景和代码示例
  • 模式选择的最佳实践和注意事项
  • 避免常见陷阱的专业建议
  • 提升代码可维护性和扩展性的实战技巧

📊 设计模式分类总览

mermaid

🏗️ 创建型模式 (Creational Patterns)

🏭 工厂模式 (Factory Pattern)

现实场景:想象你在建房子需要门,你不会每次都亲自制作,而是从工厂购买。

核心思想:将对象创建逻辑封装起来,客户端无需知道具体实现细节。

// 门接口
class WoodenDoor {
  constructor(width, height) {
    this.width = width;
    this.height = height;
  }

  getWidth() { return this.width; }
  getHeight() { return this.height; }
}

// 工厂
const DoorFactory = {
  makeDoor: (width, height) => new WoodenDoor(width, height)
};

// 使用
const door = DoorFactory.makeDoor(100, 200);
console.log('Width:', door.getWidth());  // 100
console.log('Height:', door.getHeight()); // 200

适用场景:当对象创建逻辑复杂或需要统一管理时。

🔨 抽象工厂 (Abstract Factory)

现实场景:木门需要木匠,铁门需要焊工,不同材质的门需要对应的专家。

核心思想:创建相关或依赖对象的家族,而无需指定具体类。

// 抽象产品族
class WoodenDoor {
  getDescription() { console.log('I am a wooden door'); }
}

class IronDoor {
  getDescription() { console.log('I am an iron door'); }
}

class Carpenter {
  getDescription() { console.log('I can only fit wooden doors'); }
}

class Welder {
  getDescription() { console.log('I can only fit iron doors'); }
}

// 抽象工厂
class WoodenDoorFactory {
  makeDoor() { return new WoodenDoor(); }
  makeFittingExpert() { return new Carpenter(); }
}

class IronDoorFactory {
  makeDoor() { return new IronDoor(); }
  makeFittingExpert() { return new Welder(); }
}

👷 建造者模式 (Builder Pattern)

解决痛点:避免构造器参数爆炸(Telescoping Constructor Anti-Pattern)

class Burger {
  constructor(builder) {
    this.size = builder.size;
    this.cheese = builder.cheese || false;
    this.pepperoni = builder.pepperoni || false;
    this.lettuce = builder.lettuce || false;
    this.tomato = builder.tomato || false;
  }
}

class BurgerBuilder {
  constructor(size) { this.size = size; }
  
  addCheese() { this.cheese = true; return this; }
  addPepperoni() { this.pepperoni = true; return this; }
  addLettuce() { this.lettuce = true; return this; }
  addTomato() { this.tomato = true; return this; }
  
  build() { return new Burger(this); }
}

// 链式调用
const burger = new BurgerBuilder(14)
  .addPepperoni()
  .addLettuce()
  .addTomato()
  .build();

🐑 原型模式 (Prototype Pattern)

JavaScript特色:利用原生原型机制实现对象克隆

class Sheep {
  constructor(name, category = "Mountain Sheep") {
    this.name = name;
    this.category = category;
  }
  
  setName(name) { this.name = name; }
  getName() { return this.name; }
}

// 使用JavaScript内置原型
const original = new Sheep("Jolly");
const cloned = Object.create(Object.getPrototypeOf(original));
Object.assign(cloned, original);
cloned.setName("Dolly");

console.log(original.getName()); // Jolly
console.log(cloned.getName());   // Dolly

💍 单例模式 (Singleton Pattern)

注意事项:单例模式被认为是反模式,应谨慎使用

const Leader = (function() {
  let instance;
  
  function createInstance() {
    const privateInfo = 'Super private';
    const name = 'Leader Name';
    
    return {
      getName: () => name,
      getPrivateInfo: () => privateInfo
    };
  }
  
  return {
    getInstance: function() {
      if (!instance) {
        instance = createInstance();
      }
      return instance;
    }
  };
})();

const leader1 = Leader.getInstance();
const leader2 = Leader.getInstance();
console.log(leader1 === leader2); // true

🧱 结构型模式 (Structural Patterns)

🔌 适配器模式 (Adapter Pattern)

现实场景:不同类型的充电器转换头

// 目标接口
class Lion {
  roar() {}
}

// 需要适配的类
class WildDog {
  bark() { console.log('Bark!'); }
}

// 适配器
class WildDogAdapter extends Lion {
  constructor(dog) {
    super();
    this.dog = dog;
  }
  
  roar() { this.dog.bark(); }
}

// 使用
const dog = new WildDog();
const adaptedDog = new WildDogAdapter(dog);
adaptedDog.roar(); // Bark!

🚡 桥接模式 (Bridge Pattern)

核心思想:抽象与实现分离,支持多维度变化

// 实现层次
class Theme {
  getColor() {}
}

class DarkTheme extends Theme {
  getColor() { return 'Dark Black'; }
}

class LightTheme extends Theme {
  getColor() { return 'Off White'; }
}

// 抽象层次
class WebPage {
  constructor(theme) { this.theme = theme; }
  getContent() {}
}

class AboutPage extends WebPage {
  getContent() { return `About page in ${this.theme.getColor()}`; }
}

class CareersPage extends WebPage {
  getContent() { return `Careers page in ${this.theme.getColor()}`; }
}

🌿 组合模式 (Composite Pattern)

适用场景:处理树形结构数据,统一对待单个对象和组合对象

class Employee {
  constructor(name, salary) {
    this.name = name;
    this.salary = salary;
  }
  
  getName() { return this.name; }
  getSalary() { return this.salary; }
  getRoles() { return this.roles; }
}

class Organization {
  constructor() { this.employees = []; }
  
  addEmployee(employee) { this.employees.push(employee); }
  
  getNetSalaries() {
    return this.employees.reduce((total, emp) => total + emp.getSalary(), 0);
  }
}

// 使用
const org = new Organization();
org.addEmployee(new Employee('John', 10000));
org.addEmployee(new Employee('Jane', 12000));
console.log(org.getNetSalaries()); // 22000

☕ 装饰器模式 (Decorator Pattern)

JavaScript实现:利用高阶函数和类继承

class Coffee {
  getCost() { return 10; }
  getDescription() { return 'Simple coffee'; }
}

// 装饰器基类
class CoffeeDecorator {
  constructor(coffee) { this.coffee = coffee; }
  getCost() { return this.coffee.getCost(); }
  getDescription() { return this.coffee.getDescription(); }
}

class MilkDecorator extends CoffeeDecorator {
  getCost() { return super.getCost() + 2; }
  getDescription() { return super.getDescription() + ', milk'; }
}

class WhipDecorator extends CoffeeDecorator {
  getCost() { return super.getCost() + 5; }
  getDescription() { return super.getDescription() + ', whip'; }
}

// 使用
let coffee = new Coffee();
coffee = new MilkDecorator(coffee);
coffee = new WhipDecorator(coffee);

console.log(coffee.getCost()); // 17
console.log(coffee.getDescription()); // Simple coffee, milk, whip

📦 外观模式 (Facade Pattern)

现实场景:电脑开机按钮背后复杂的启动流程

class Computer {
  getElectricShock() { console.log('Ouch!'); }
  makeSound() { console.log('Beep beep!'); }
  showLoadingScreen() { console.log('Loading..'); }
  bam() { console.log('Ready!'); }
  closeEverything() { console.log('Closing..'); }
  sooth() { console.log('Zzzzz'); }
}

class ComputerFacade {
  constructor(computer) { this.computer = computer; }
  
  turnOn() {
    this.computer.getElectricShock();
    this.computer.makeSound();
    this.computer.showLoadingScreen();
    this.computer.bam();
  }
  
  turnOff() {
    this.computer.closeEverything();
    this.computer.sooth();
  }
}

// 简化接口
const computer = new ComputerFacade(new Computer());
computer.turnOn();  // 复杂的启动过程
computer.turnOff(); // 复杂的关闭过程

🔄 行为型模式 (Behavioral Patterns)

👀 观察者模式 (Observer Pattern)

现代JavaScript实现:使用Proxy和Set

class Observable {
  constructor() {
    this.observers = new Set();
  }
  
  subscribe(observer) {
    this.observers.add(observer);
    return () => this.observers.delete(observer);
  }
  
  notify(data) {
    this.observers.forEach(observer => observer(data));
  }
}

// 使用
const observable = new Observable();

const unsubscribe = observable.subscribe(data => {
  console.log('Observer 1:', data);
});

observable.subscribe(data => {
  console.log('Observer 2:', data);
});

observable.notify('Hello World!');
// Observer 1: Hello World!
// Observer 2: Hello World!

unsubscribe();
observable.notify('After unsubscribe');
// Observer 2: After unsubscribe

🎯 策略模式 (Strategy Pattern)

适用场景:多种算法或策略,客户端可动态选择

class PaymentStrategy {
  pay(amount) {}
}

class CreditCardStrategy extends PaymentStrategy {
  pay(amount) {
    console.log(`Paid ${amount} using Credit Card`);
  }
}

class PayPalStrategy extends PaymentStrategy {
  pay(amount) {
    console.log(`Paid ${amount} using PayPal`);
  }
}

class ShoppingCart {
  constructor() {
    this.amount = 0;
    this.strategy = null;
  }
  
  setPaymentStrategy(strategy) {
    this.strategy = strategy;
  }
  
  checkout() {
    if (this.strategy) {
      this.strategy.pay(this.amount);
    } else {
      console.log('No payment strategy set');
    }
  }
}

📈 设计模式选择指南

问题场景推荐模式优点
对象创建复杂工厂模式/建造者封装创建逻辑,降低耦合
需要家族相关对象抽象工厂确保对象兼容性
对象开销大原型模式通过克隆减少开销
接口不兼容适配器模式使不兼容接口协同工作
抽象与实现分离桥接模式支持多维度变化
树形结构处理组合模式统一对待个体和组合
动态添加功能装饰器模式遵循开闭原则
复杂子系统外观模式提供简化接口
对象状态变化状态模式封装状态相关行为
多种算法选择策略模式灵活切换算法

🚀 最佳实践与注意事项

✅ 该做的

  • 适时使用模式:只在真正需要时引入设计模式
  • 保持简单:优先选择简单解决方案
  • 遵循SOLID原则:确保模式应用符合设计原则
  • 考虑JavaScript特性:利用语言特性简化模式实现

❌ 不该做的

  • 过度设计:不要为了模式而模式
  • 忽视性能:某些模式可能带来性能开销
  • 违反YAGNI:不要提前实现可能不需要的功能
  • 忽略可读性:模式应该提高代码可读性,而不是降低

🎓 学习路径建议

mermaid

📝 总结

设计模式是解决特定问题的经验总结,但不是银弹。在JavaScript中应用设计模式时:

  1. 理解问题本质:确保模式真正解决你的问题
  2. 利用语言特性:JavaScript的动态特性可以简化某些模式
  3. 保持代码简洁:避免过度工程化
  4. 注重可维护性:模式应该让代码更易理解和维护

记住:最好的模式是适合当前场景的模式。不要生搬硬套,而是根据具体需求灵活选择和调整。

掌握设计模式就像获得了一套强大的工具箱,但真正的艺术在于知道何时使用哪件工具。

【免费下载链接】javascript-design-patterns-for-humans An ultra-simplified explanation of design patterns implemented in javascript 【免费下载链接】javascript-design-patterns-for-humans 项目地址: https://gitcode.com/gh_mirrors/ja/javascript-design-patterns-for-humans

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值