工厂模式与单例模式
工厂模式解决对象创建问题,单例模式保证唯一实例,两者是前端开发中最常用的创建型模式。
工厂模式
简单工厂
JavaScript
class User {
constructor(name, role) {
this.name = name;
this.role = role;
}
}
class UserFactory {
static create(name, type) {
switch (type) {
case 'admin':
return new User(name, 'admin');
case 'member':
return new User(name, 'member');
case 'guest':
return new User(name, 'guest');
default:
throw new Error('Invalid user type');
}
}
}
// 使用
const admin = UserFactory.create('Alice', 'admin');
const guest = UserFactory.create('Bob', 'guest');
工厂方法
JavaScript
// 产品接口
class Button {
render() {
throw new Error('Must implement render');
}
}
class HTMLButton extends Button {
render() {
return '<button>HTML Button</button>';
}
}
class WindowsButton extends Button {
render() {
return 'Windows Button Control';
}
}
// 工厂接口
class Dialog {
createButton() {
throw new Error('Must implement createButton');
}
render() {
const button = this.createButton();
return button.render();
}
}
// 具体工厂
class HTMLDialog extends Dialog {
createButton() {
return new HTMLButton();
}
}
class WindowsDialog extends Dialog {
createButton() {
return new WindowsButton();
}
}
// 使用
const dialog = new HTMLDialog();
dialog.render();
抽象工厂
JavaScript
// 产品族
class ThemeFactory {
createButton() {}
createInput() {}
createCheckbox() {}
}
class DarkThemeFactory extends ThemeFactory {
createButton() {
return { type: 'button', color: '#333', background: '#111' };
}
createInput() {
return { type: 'input', color: '#fff', background: '#222' };
}
createCheckbox() {
return { type: 'checkbox', checkedColor: '#666' };
}
}
class LightThemeFactory extends ThemeFactory {
createButton() {
return { type: 'button', color: '#fff', background: '#007bff' };
}
createInput() {
return { type: 'input', color: '#333', background: '#fff' };
}
createCheckbox() {
return { type: 'checkbox', checkedColor: '#007bff' };
}
}
// 使用
function createUI(factory) {
return {
button: factory.createButton(),
input: factory.createInput(),
checkbox: factory.createCheckbox()
};
}
const darkUI = createUI(new DarkThemeFactory());
单例模式
基础实现
JavaScript
class Singleton {
constructor() {
if (Singleton.instance) {
return Singleton.instance;
}
Singleton.instance = this;
}
static getInstance() {
if (!Singleton.instance) {
Singleton.instance = new Singleton();
}
return Singleton.instance;
}
}
// 使用
const a = new Singleton();
const b = new Singleton();
console.log(a === b); // true
闭包实现
JavaScript
const Singleton = (function () {
let instance;
function createInstance() {
return {
name: 'Singleton',
method() {
return 'Singleton method';
}
};
}
return {
getInstance() {
if (!instance) {
instance = createInstance();
}
return instance;
}
};
})();
// 使用
const instance1 = Singleton.getInstance();
const instance2 = Singleton.getInstance();
console.log(instance1 === instance2); // true
ES6模块单例
JavaScript
// config.js - ES6模块天然支持单例
const config = {
apiBaseUrl: 'https://api.example.com',
timeout: 5000,
theme: 'dark'
};
export default config;
// 多次导入获得同一实例
import config from './config.js';
懒加载单例
JavaScript
class Database {
constructor() {
this.connection = null;
}
async connect() {
if (!this.connection) {
this.connection = await createConnection();
}
return this.connection;
}
static getInstance() {
if (!Database.instance) {
Database.instance = new Database();
}
return Database.instance;
}
}
// 按需连接
const db = Database.getInstance();
await db.connect();
实际应用场景
工厂模式应用
JavaScript
// HTTP请求工厂
class RequestFactory {
static create(config) {
const { type = 'json' } = config;
switch (type) {
case 'json':
return new JsonRequest(config);
case 'form':
return new FormRequest(config);
case 'multipart':
return new MultipartRequest(config);
default:
return new BaseRequest(config);
}
}
}
// 使用
const request = RequestFactory.create({ url: '/api', type: 'json' });
request.send();
单例模式应用
JavaScript
// 全局状态管理
class StateManager {
constructor() {
if (StateManager.instance) {
return StateManager.instance;
}
this.state = {};
this.listeners = [];
StateManager.instance = this;
}
setState(newState) {
this.state = { ...this.state, ...newState };
this.listeners.forEach(fn => fn(this.state));
}
subscribe(fn) {
this.listeners.push(fn);
return () => {
this.listeners = this.listeners.filter(l => l !== fn);
};
}
}
// 全局唯一状态实例
const store = new StateManager();
模式对比
| 特性 | 简单工厂 | 工厂方法 | 抽象工厂 | 单例 |
|---|---|---|---|---|
| 目的 | 创建单一对象 | 创建对象 | 创建产品族 | 唯一实例 |
| 扩展性 | 需修改工厂 | 新增工厂 | 新增工厂 | - |
| 复杂度 | 低 | 中 | 高 | 低 |
工厂模式解决"创建什么"的问题,单例模式解决"创建几个"的问题。
要点总结
- 简单工厂:集中创建逻辑,适合简单场景
- 工厂方法:延迟创建到子类,符合开闭原则
- 抽象工厂:创建产品族,保证产品兼容性
- 单例核心:私有构造函数 + 静态实例
- 单例注意:全局状态污染、测试困难、需谨慎使用
存放路径:articles/JS/专家/设计模式与架构思想/工厂模式与单例模式.md
📝 发现内容有误?点击此处直接编辑