设计模式(Design Patterns)是软件开发中针对常见问题的可重用解决方案。它们是从经验中总结出来的最佳实践,帮助开发者编写可维护、可扩展和高效的代码。设计模式通常分为三大类:创建型 、结构型 和 行为型。
一、创建型模式
关注对象的创建方式,旨在使系统独立于对象的创建、组合和表示。
1. 单例模式(Singleton)
-
作用:确保一个类只有一个实例,并提供全局访问点。
-
应用场景:数据库连接池、日志记录器。
-
示例 :
javascriptclass Singleton { constructor() { if (!Singleton.instance) { Singleton.instance = this; } return Singleton.instance; } } const instance1 = new Singleton(); const instance2 = new Singleton(); console.log(instance1 === instance2); // true
2. 工厂模式(Factory)
-
作用:定义一个创建对象的接口,由子类决定实例化哪个类。
-
应用场景:创建复杂对象、解耦对象创建与使用。
-
示例 :
javascriptclass ProductA {} class ProductB {} class Factory { createProduct(type) { switch (type) { case 'A': return new ProductA(); case 'B': return new ProductB(); default: throw new Error('Unknown product type'); } } } const factory = new Factory(); const productA = factory.createProduct('A');
3. 建造者模式(Builder)
-
作用:将一个复杂对象的构建与其表示分离,使同样的构建过程可以创建不同的表示。
-
应用场景:创建复杂对象(如 DOM 元素、HTTP 请求)。
-
示例 :
javascriptclass Product { constructor() { this.parts = []; } addPart(part) { this.parts.push(part); } show() { console.log(this.parts.join(', ')); } } class Builder { buildPartA() {} buildPartB() {} getResult() {} } class ConcreteBuilder extends Builder { constructor() { super(); this.product = new Product(); } buildPartA() { this.product.addPart('PartA'); } buildPartB() { this.product.addPart('PartB'); } getResult() { return this.product; } } const builder = new ConcreteBuilder(); builder.buildPartA(); builder.buildPartB(); const product = builder.getResult(); product.show(); // PartA, PartB
二、结构型模式
关注类和对象的组合,形成更大的结构。
1. 适配器模式(Adapter)
-
作用:将一个类的接口转换成客户希望的另一个接口。
-
应用场景:兼容旧代码、集成第三方库。
-
示例 :
javascriptclass OldService { request() { return 'Old service response'; } } class Adapter { constructor(oldService) { this.oldService = oldService; } newRequest() { const result = this.oldService.request(); return `Adapted: ${result}`; } } const oldService = new OldService(); const adapter = new Adapter(oldService); console.log(adapter.newRequest()); // Adapted: Old service response
2. 装饰器模式(Decorator)
-
作用:动态地为对象添加功能。
-
应用场景:扩展对象功能、避免子类膨胀。
-
示例 :
javascriptclass Coffee { cost() { return 5; } } class MilkDecorator { constructor(coffee) { this.coffee = coffee; } cost() { return this.coffee.cost() + 2; } } const coffee = new Coffee(); const milkCoffee = new MilkDecorator(coffee); console.log(milkCoffee.cost()); // 7
3. 代理模式(Proxy)
-
作用:为其他对象提供一个代理以控制对这个对象的访问。
-
应用场景:延迟加载、权限控制。
-
示例 :
javascriptclass RealImage { constructor(filename) { this.filename = filename; this.loadFromDisk(); } display() { console.log(`Displaying ${this.filename}`); } loadFromDisk() { console.log(`Loading ${this.filename}`); } } class ProxyImage { constructor(filename) { this.filename = filename; this.realImage = null; } display() { if (!this.realImage) { this.realImage = new RealImage(this.filename); } this.realImage.display(); } } const image = new ProxyImage('test.jpg'); image.display(); // Loading test.jpg -> Displaying test.jpg
三、行为型模式
关注对象之间的职责分配和通信。
1. 观察者模式(Observer)
-
作用:定义对象间的一对多依赖关系,当一个对象改变状态时,所有依赖者都会收到通知。
-
应用场景:事件处理系统、数据绑定。
-
示例 :
javascriptclass Subject { constructor() { this.observers = []; } addObserver(observer) { this.observers.push(observer); } notify(data) { this.observers.forEach(observer => observer.update(data)); } } class Observer { update(data) { console.log(`Received data: ${data}`); } } const subject = new Subject(); const observer = new Observer(); subject.addObserver(observer); subject.notify('Hello!'); // Received data: Hello!
2. 策略模式(Strategy)
-
作用:定义一系列算法,将它们封装起来并使它们可以互换。
-
应用场景:动态选择算法、避免多重条件判断。
-
示例 :
javascriptclass StrategyA { execute() { console.log('Strategy A'); } } class StrategyB { execute() { console.log('Strategy B'); } } class Context { constructor(strategy) { this.strategy = strategy; } executeStrategy() { this.strategy.execute(); } } const contextA = new Context(new StrategyA()); contextA.executeStrategy(); // Strategy A const contextB = new Context(new StrategyB()); contextB.executeStrategy(); // Strategy B
3. 命令模式(Command)
-
作用:将请求封装为对象,使你可以用不同的请求对客户进行参数化。
-
应用场景:撤销/重做操作、任务队列。
-
示例 :
javascriptclass Receiver { action() { console.log('Action performed'); } } class Command { constructor(receiver) { this.receiver = receiver; } execute() { this.receiver.action(); } } class Invoker { setCommand(command) { this.command = command; } executeCommand() { this.command.execute(); } } const receiver = new Receiver(); const command = new Command(receiver); const invoker = new Invoker(); invoker.setCommand(command); invoker.executeCommand(); // Action performed
四、总结
设计模式是软件开发中的宝贵工具,能够帮助开发者编写更优雅、可维护的代码。以下是选择设计模式时的建议:
- 明确问题:先理解问题,再选择合适的设计模式。
- 避免过度设计:不要为了使用设计模式而使用。
- 结合语言特性:不同编程语言可能有更适合的实现方式。
通过掌握设计模式,开发者可以更好地应对复杂系统的设计和开发挑战。