JavaScript 创建型设计模式详解
1. 单例模式
1.1. 使用场景
在前端开发中,全局状态管理、配置信息、数据库连接等往往需要在应用中只存在一个实例,避免多次实例化带来的数据不一致性。例如,在一个前端应用中,全局的 loading 状态通常需要一个单例模式来确保其唯一性。
1.2. 代码实现
class Singleton {// 构造函数为私有,防止外部直接调用constructor() {if (Singleton.instance) {return Singleton.instance;}// 初始化其他属性this.data = [];Singleton.instance = this;}// 静态方法,获取唯一的实例static getInstance() {if (!Singleton.instance) {Singleton.instance = new Singleton();}return Singleton.instance;}// 添加数据方法addData(item) {this.data.push(item);}// 获取数据方法getData() {return this.data;}
}// 使用 Singleton
const instance1 = Singleton.getInstance();
instance1.addData('First Item');const instance2 = Singleton.getInstance();
console.log(instance2.getData()); // ['First Item'], instance1 和 instance2 是同一个实例
1.3. 详细注释
constructor():将构造函数私有化,通过判断 Singleton.instance 是否已存在来确保单例。
getInstance():静态方法用于获取唯一实例,调用时如果实例不存在则创建新实例,存在则直接返回已有实例。
使用 addData 和 getData 方法演示单例模式下的数据存储与获取,保证所有调用的是同一个实例。
1.4. 实际应用
- 单例模式可用于前端中的全局配置对象、全局状态管理(如 Redux Store)、全局事件总线等。
2. 工厂方法模式
2.1. 使用场景
当我们需要创建不同类型的对象但又不想在代码中写死实例化的逻辑时,工厂方法模式能够根据条件动态生成合适的对象实例。在前端开发中,常用于根据不同配置生成相应的组件或对象。
2.2. 代码实现
class Button {constructor(type) {this.type = type;}render() {console.log(`Render a ${this.type} button`);}
}class ButtonFactory {createButton(type) {switch (type) {case 'primary':return new Button('primary');case 'secondary':return new Button('secondary');default:throw new Error('Button type not supported');}}
}// 使用工厂方法
const factory = new ButtonFactory();
const primaryButton = factory.createButton('primary');
primaryButton.render(); // Render a primary button
2.3. 详细注释
Button:表示一个具体的按钮对象,通过 type 来区分不同类型的按钮。
ButtonFactory:工厂类用于创建不同类型的按钮对象,提供了 createButton 方法,根据传入的 type 动态生成对应的实例。
通过工厂方法来解耦实例化逻辑和对象使用,便于扩展。
2.4. 实际应用
- 工厂方法模式常用于创建复杂的对象实例,例如组件库中的动态组件生成、API 服务实例化等。
3. 抽象工厂模式
3.1. 使用场景
当需要创建一组相关或相互依赖的对象时,抽象工厂模式能帮助我们统一创建流程。在前端框架中,常用于根据环境或用户设置来创建不同的一组 UI 组件或工具。
3.2. 代码实现
class MacButton {render() {console.log('Render a Mac button');}
}class WindowsButton {render() {console.log('Render a Windows button');}
}class MacFactory {createButton() {return new MacButton();}
}class WindowsFactory {createButton() {return new WindowsButton();}
}function createUI(factory) {const button = factory.createButton();button.render();
}// 使用抽象工厂
const macFactory = new MacFactory();
createUI(macFactory); // Render a Mac buttonconst windowsFactory = new WindowsFactory();
createUI(windowsFactory); // Render a Windows button
3.3. 详细注释
MacButton 与 WindowsButton:表示不同平台下的按钮组件。
MacFactory 与 WindowsFactory:各自负责创建相应平台的组件,通过 createButton 方法创建相应的按钮对象。
通过抽象工厂模式,确保了创建一整套相关联对象的流程简单统一。
3.4. 实际应用
抽象工厂模式广泛用于创建跨平台 UI 组件、表单控件等场景。
4. 建造者模式
4.1. 使用场景
当一个对象的创建需要依赖多个步骤或者多个部分时,建造者模式能通过逐步构建的方式来确保创建流程的清晰和可控。适合在前端复杂组件的创建中使用,例如动态表单、复杂配置对象等。
4.2. 代码实现
class Form {constructor() {this.fields = [];}addField(field) {this.fields.push(field);}getForm() {return this.fields;}
}class FormBuilder {constructor() {this.form = new Form();}addTextField(label) {this.form.addField({ type: 'text', label });return this;}addCheckboxField(label) {this.form.addField({ type: 'checkbox', label });return this;}build() {return this.form;}
}// 使用建造者模式
const formBuilder = new FormBuilder();
const form = formBuilder.addTextField('Name').addCheckboxField('Subscribe').build();console.log(form.getForm()); // [{type: 'text', label: 'Name'}, {type: 'checkbox', label: 'Subscribe'}]
4.3. 详细注释
Form:表示表单对象,包含表单字段的数组。
FormBuilder:提供了一系列方法,用于动态添加表单字段,通过 build 方法返回构建好的表单。
通过建造者模式,可以灵活地构建复杂对象,同时保持代码的简洁和可读性。
4.4. 实际应用
- 建造者模式常用于创建多步骤配置的对象,如复杂的 UI 组件、表单生成器、配置对象等。
5. 原型模式
5.1. 使用场景
当我们需要快速创建对象的副本时,原型模式可以通过拷贝已有对象来避免重复的初始化操作。常用于需要大量类似对象的场景,如渲染大量类似的 UI 组件或节点。
5.2. 代码实现
class Prototype {constructor(data) {this.data = data;}clone() {return new Prototype(this.data);}
}// 使用原型模式
const original = new Prototype({ name: 'Original' });
const clone = original.clone();console.log(original.data); // { name: 'Original' }
console.log(clone.data); // { name: 'Original' }
console.log(original === clone); // false
5.3. 详细注释
Prototype:表示原型对象,提供了 clone 方法用于创建对象的副本。
clone():返回一个新对象,拷贝了原对象的数据,实现了对象的快速复制。
原型模式避免了重新创建和初始化对象的复杂性。
5.4. 实际应用
- 原型模式常用于需要大量创建相似对象的场景,如游戏开发中的对象克隆、前端应用中的组件渲染等。