Search K
Appearance
Appearance
📊 SEO元描述:2024年最新JavaScript工厂模式教程,详解简单工厂模式、工厂方法模式、抽象工厂模式。包含完整实战案例,适合前端开发者掌握创建型设计模式。
核心关键词:JavaScript工厂模式2024、工厂设计模式、简单工厂模式、工厂方法模式、抽象工厂模式、JavaScript设计模式
长尾关键词:JavaScript工厂模式怎么实现、工厂模式应用场景、JavaScript设计模式最佳实践、前端工厂模式优缺点、抽象工厂模式实现
通过本节JavaScript工厂模式完整指南,你将系统性掌握:
工厂模式是什么?这是创建型设计模式中最重要的模式之一。工厂模式(Factory Pattern)是指通过工厂类来创建对象,而不是直接使用new操作符创建对象的设计模式,也是面向对象编程中封装对象创建逻辑的核心技术。
💡 设计模式建议:工厂模式是解决对象创建复杂性的最佳方案,特别适用于需要根据条件创建不同类型对象的场景。
简单工厂模式通过一个工厂类根据参数创建不同类型的对象,是最基础的工厂模式实现。
// 🎉 简单工厂模式实现
// 产品基类
class Shape {
constructor(type) {
this.type = type;
}
draw() {
throw new Error('draw method must be implemented');
}
getArea() {
throw new Error('getArea method must be implemented');
}
getInfo() {
return {
type: this.type,
area: this.getArea()
};
}
}
// 具体产品类
class Circle extends Shape {
constructor(radius) {
super('Circle');
this.radius = radius;
}
draw() {
console.log(`Drawing a circle with radius ${this.radius}`);
return `<circle r="${this.radius}" />`;
}
getArea() {
return Math.PI * this.radius * this.radius;
}
}
class Rectangle extends Shape {
constructor(width, height) {
super('Rectangle');
this.width = width;
this.height = height;
}
draw() {
console.log(`Drawing a rectangle ${this.width}x${this.height}`);
return `<rect width="${this.width}" height="${this.height}" />`;
}
getArea() {
return this.width * this.height;
}
}
class Triangle extends Shape {
constructor(base, height) {
super('Triangle');
this.base = base;
this.height = height;
}
draw() {
console.log(`Drawing a triangle with base ${this.base} and height ${this.height}`);
return `<polygon points="0,${this.height} ${this.base/2},0 ${this.base},${this.height}" />`;
}
getArea() {
return (this.base * this.height) / 2;
}
}
// 简单工厂类
class ShapeFactory {
static createShape(type, ...args) {
switch (type.toLowerCase()) {
case 'circle':
return new Circle(args[0]);
case 'rectangle':
return new Rectangle(args[0], args[1]);
case 'triangle':
return new Triangle(args[0], args[1]);
default:
throw new Error(`Unknown shape type: ${type}`);
}
}
// 支持配置对象的创建方式
static createShapeFromConfig(config) {
const { type, ...params } = config;
switch (type.toLowerCase()) {
case 'circle':
return new Circle(params.radius);
case 'rectangle':
return new Rectangle(params.width, params.height);
case 'triangle':
return new Triangle(params.base, params.height);
default:
throw new Error(`Unknown shape type: ${type}`);
}
}
// 批量创建
static createShapes(configs) {
return configs.map(config => this.createShapeFromConfig(config));
}
// 获取支持的形状类型
static getSupportedTypes() {
return ['circle', 'rectangle', 'triangle'];
}
// 验证配置
static validateConfig(config) {
const { type } = config;
if (!type) {
throw new Error('Shape type is required');
}
if (!this.getSupportedTypes().includes(type.toLowerCase())) {
throw new Error(`Unsupported shape type: ${type}`);
}
switch (type.toLowerCase()) {
case 'circle':
if (!config.radius || config.radius <= 0) {
throw new Error('Circle requires a positive radius');
}
break;
case 'rectangle':
if (!config.width || !config.height || config.width <= 0 || config.height <= 0) {
throw new Error('Rectangle requires positive width and height');
}
break;
case 'triangle':
if (!config.base || !config.height || config.base <= 0 || config.height <= 0) {
throw new Error('Triangle requires positive base and height');
}
break;
}
return true;
}
}
// 高级简单工厂 - 支持插件式扩展
class AdvancedShapeFactory {
constructor() {
this.creators = new Map();
this.validators = new Map();
// 注册默认创建器
this.registerCreator('circle', (config) => new Circle(config.radius));
this.registerCreator('rectangle', (config) => new Rectangle(config.width, config.height));
this.registerCreator('triangle', (config) => new Triangle(config.base, config.height));
// 注册默认验证器
this.registerValidator('circle', (config) => {
if (!config.radius || config.radius <= 0) {
throw new Error('Circle requires a positive radius');
}
});
this.registerValidator('rectangle', (config) => {
if (!config.width || !config.height || config.width <= 0 || config.height <= 0) {
throw new Error('Rectangle requires positive width and height');
}
});
this.registerValidator('triangle', (config) => {
if (!config.base || !config.height || config.base <= 0 || config.height <= 0) {
throw new Error('Triangle requires positive base and height');
}
});
}
registerCreator(type, creator) {
this.creators.set(type.toLowerCase(), creator);
return this;
}
registerValidator(type, validator) {
this.validators.set(type.toLowerCase(), validator);
return this;
}
createShape(config) {
const type = config.type.toLowerCase();
// 验证配置
if (this.validators.has(type)) {
this.validators.get(type)(config);
}
// 创建对象
if (this.creators.has(type)) {
return this.creators.get(type)(config);
}
throw new Error(`Unknown shape type: ${config.type}`);
}
getSupportedTypes() {
return Array.from(this.creators.keys());
}
hasType(type) {
return this.creators.has(type.toLowerCase());
}
}
// 使用示例
console.log('=== 简单工厂模式测试 ===');
// 基础使用
const circle = ShapeFactory.createShape('circle', 5);
const rectangle = ShapeFactory.createShape('rectangle', 10, 8);
const triangle = ShapeFactory.createShape('triangle', 6, 4);
console.log('Circle area:', circle.getArea());
console.log('Rectangle area:', rectangle.getArea());
console.log('Triangle area:', triangle.getArea());
// 配置对象方式
const shapes = ShapeFactory.createShapes([
{ type: 'circle', radius: 3 },
{ type: 'rectangle', width: 5, height: 7 },
{ type: 'triangle', base: 8, height: 6 }
]);
shapes.forEach(shape => {
console.log(shape.getInfo());
});
// 高级工厂使用
const advancedFactory = new AdvancedShapeFactory();
// 扩展新的形状类型
class Ellipse extends Shape {
constructor(a, b) {
super('Ellipse');
this.a = a; // 长半轴
this.b = b; // 短半轴
}
draw() {
console.log(`Drawing an ellipse with semi-axes ${this.a} and ${this.b}`);
return `<ellipse rx="${this.a}" ry="${this.b}" />`;
}
getArea() {
return Math.PI * this.a * this.b;
}
}
// 注册新类型
advancedFactory.registerCreator('ellipse', (config) => new Ellipse(config.a, config.b));
advancedFactory.registerValidator('ellipse', (config) => {
if (!config.a || !config.b || config.a <= 0 || config.b <= 0) {
throw new Error('Ellipse requires positive semi-axes a and b');
}
});
const ellipse = advancedFactory.createShape({ type: 'ellipse', a: 4, b: 3 });
console.log('Ellipse info:', ellipse.getInfo());工厂方法模式通过抽象工厂类定义创建接口,具体工厂类实现创建逻辑,支持更好的扩展性。
// 🎉 工厂方法模式实现
// 抽象产品类
class Logger {
constructor(name) {
this.name = name;
this.created = new Date();
}
log(level, message, ...args) {
throw new Error('log method must be implemented');
}
info(message, ...args) {
this.log('INFO', message, ...args);
}
warn(message, ...args) {
this.log('WARN', message, ...args);
}
error(message, ...args) {
this.log('ERROR', message, ...args);
}
debug(message, ...args) {
this.log('DEBUG', message, ...args);
}
}
// 具体产品类
class ConsoleLogger extends Logger {
constructor(name, options = {}) {
super(name);
this.colorEnabled = options.colorEnabled !== false;
this.timestampEnabled = options.timestampEnabled !== false;
}
log(level, message, ...args) {
const timestamp = this.timestampEnabled ?
`[${new Date().toISOString()}] ` : '';
const prefix = `${timestamp}[${level}] [${this.name}]`;
if (this.colorEnabled) {
const colors = {
INFO: '\x1b[36m', // cyan
WARN: '\x1b[33m', // yellow
ERROR: '\x1b[31m', // red
DEBUG: '\x1b[90m' // gray
};
const reset = '\x1b[0m';
const color = colors[level] || '';
console.log(`${color}${prefix}${reset}`, message, ...args);
} else {
console.log(prefix, message, ...args);
}
}
}
class FileLogger extends Logger {
constructor(name, options = {}) {
super(name);
this.filename = options.filename || `${name}.log`;
this.maxSize = options.maxSize || 10 * 1024 * 1024; // 10MB
this.logs = [];
}
log(level, message, ...args) {
const timestamp = new Date().toISOString();
const logEntry = {
timestamp,
level,
logger: this.name,
message,
args: args.length > 0 ? args : undefined
};
this.logs.push(logEntry);
// 模拟写入文件
this.writeToFile(logEntry);
// 检查文件大小限制
if (this.logs.length > 1000) {
this.rotateLogs();
}
}
writeToFile(logEntry) {
// 在实际应用中,这里会写入到文件系统
const logLine = `${logEntry.timestamp} [${logEntry.level}] [${logEntry.logger}] ${logEntry.message}`;
console.log(`[FILE: ${this.filename}] ${logLine}`);
}
rotateLogs() {
// 日志轮转逻辑
const oldLogs = this.logs.splice(0, 500);
console.log(`Rotated ${oldLogs.length} log entries from ${this.filename}`);
}
getLogs(level = null, limit = 100) {
let filteredLogs = this.logs;
if (level) {
filteredLogs = this.logs.filter(log => log.level === level);
}
return filteredLogs.slice(-limit);
}
}
class RemoteLogger extends Logger {
constructor(name, options = {}) {
super(name);
this.endpoint = options.endpoint || '/api/logs';
this.batchSize = options.batchSize || 10;
this.flushInterval = options.flushInterval || 5000;
this.buffer = [];
this.startFlushTimer();
}
log(level, message, ...args) {
const logEntry = {
timestamp: new Date().toISOString(),
level,
logger: this.name,
message,
args: args.length > 0 ? args : undefined,
userAgent: navigator.userAgent,
url: window.location.href
};
this.buffer.push(logEntry);
if (this.buffer.length >= this.batchSize) {
this.flush();
}
}
async flush() {
if (this.buffer.length === 0) return;
const logs = this.buffer.splice(0);
try {
await fetch(this.endpoint, {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({ logs })
});
console.log(`Sent ${logs.length} logs to remote server`);
} catch (error) {
console.error('Failed to send logs to remote server:', error);
// 重新加入缓冲区
this.buffer.unshift(...logs);
}
}
startFlushTimer() {
setInterval(() => {
this.flush();
}, this.flushInterval);
}
}
// 抽象工厂类
class LoggerFactory {
createLogger(name, options) {
throw new Error('createLogger method must be implemented');
}
// 模板方法 - 提供通用的创建流程
createLoggerWithValidation(name, options = {}) {
this.validateName(name);
this.validateOptions(options);
const logger = this.createLogger(name, options);
this.configureLogger(logger, options);
return logger;
}
validateName(name) {
if (!name || typeof name !== 'string') {
throw new Error('Logger name must be a non-empty string');
}
}
validateOptions(options) {
if (options && typeof options !== 'object') {
throw new Error('Logger options must be an object');
}
}
configureLogger(logger, options) {
// 通用配置逻辑
if (options.level) {
logger.level = options.level;
}
}
}
// 具体工厂类
class ConsoleLoggerFactory extends LoggerFactory {
createLogger(name, options) {
return new ConsoleLogger(name, options);
}
}
class FileLoggerFactory extends LoggerFactory {
createLogger(name, options) {
return new FileLogger(name, options);
}
validateOptions(options) {
super.validateOptions(options);
if (options.filename && typeof options.filename !== 'string') {
throw new Error('Filename must be a string');
}
if (options.maxSize && (typeof options.maxSize !== 'number' || options.maxSize <= 0)) {
throw new Error('Max size must be a positive number');
}
}
}
class RemoteLoggerFactory extends LoggerFactory {
createLogger(name, options) {
return new RemoteLogger(name, options);
}
validateOptions(options) {
super.validateOptions(options);
if (options.endpoint && typeof options.endpoint !== 'string') {
throw new Error('Endpoint must be a string');
}
if (options.batchSize && (typeof options.batchSize !== 'number' || options.batchSize <= 0)) {
throw new Error('Batch size must be a positive number');
}
}
}
// 工厂管理器
class LoggerFactoryManager {
constructor() {
this.factories = new Map();
this.defaultFactory = null;
// 注册默认工厂
this.registerFactory('console', new ConsoleLoggerFactory());
this.registerFactory('file', new FileLoggerFactory());
this.registerFactory('remote', new RemoteLoggerFactory());
this.setDefaultFactory('console');
}
registerFactory(type, factory) {
if (!(factory instanceof LoggerFactory)) {
throw new Error('Factory must be an instance of LoggerFactory');
}
this.factories.set(type, factory);
return this;
}
setDefaultFactory(type) {
if (!this.factories.has(type)) {
throw new Error(`Factory type '${type}' not registered`);
}
this.defaultFactory = type;
return this;
}
createLogger(type, name, options) {
const factoryType = type || this.defaultFactory;
if (!this.factories.has(factoryType)) {
throw new Error(`Unknown logger factory type: ${factoryType}`);
}
const factory = this.factories.get(factoryType);
return factory.createLoggerWithValidation(name, options);
}
getSupportedTypes() {
return Array.from(this.factories.keys());
}
}
// 使用示例
console.log('=== 工厂方法模式测试 ===');
const loggerManager = new LoggerFactoryManager();
// 创建不同类型的日志记录器
const consoleLogger = loggerManager.createLogger('console', 'App', {
colorEnabled: true,
timestampEnabled: true
});
const fileLogger = loggerManager.createLogger('file', 'FileApp', {
filename: 'app.log',
maxSize: 5 * 1024 * 1024
});
const remoteLogger = loggerManager.createLogger('remote', 'RemoteApp', {
endpoint: '/api/logs',
batchSize: 5,
flushInterval: 3000
});
// 使用日志记录器
consoleLogger.info('Application started');
consoleLogger.warn('This is a warning');
consoleLogger.error('This is an error');
fileLogger.info('File logging test');
fileLogger.debug('Debug information');
remoteLogger.info('Remote logging test');
remoteLogger.error('Remote error logging');
// 扩展新的日志记录器类型
class DatabaseLogger extends Logger {
constructor(name, options = {}) {
super(name);
this.tableName = options.tableName || 'logs';
this.connectionString = options.connectionString;
}
log(level, message, ...args) {
const logEntry = {
timestamp: new Date(),
level,
logger: this.name,
message,
args: JSON.stringify(args)
};
// 模拟数据库插入
console.log(`[DB: ${this.tableName}] INSERT:`, logEntry);
}
}
class DatabaseLoggerFactory extends LoggerFactory {
createLogger(name, options) {
return new DatabaseLogger(name, options);
}
validateOptions(options) {
super.validateOptions(options);
if (!options.connectionString) {
throw new Error('Database connection string is required');
}
}
}
// 注册新的工厂类型
loggerManager.registerFactory('database', new DatabaseLoggerFactory());
const dbLogger = loggerManager.createLogger('database', 'DBApp', {
connectionString: 'mongodb://localhost:27017/logs',
tableName: 'application_logs'
});
dbLogger.info('Database logging test');
console.log('Supported logger types:', loggerManager.getSupportedTypes());工厂方法模式的优势:
抽象工厂模式提供创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类。
// 🎉 抽象工厂模式实现
// 抽象产品 - UI组件
class Button {
constructor(text) {
this.text = text;
}
render() {
throw new Error('render method must be implemented');
}
onClick(handler) {
this.clickHandler = handler;
}
}
class Input {
constructor(placeholder) {
this.placeholder = placeholder;
this.value = '';
}
render() {
throw new Error('render method must be implemented');
}
setValue(value) {
this.value = value;
}
getValue() {
return this.value;
}
}
class Modal {
constructor(title, content) {
this.title = title;
this.content = content;
this.isVisible = false;
}
render() {
throw new Error('render method must be implemented');
}
show() {
this.isVisible = true;
}
hide() {
this.isVisible = false;
}
}
// Material Design 产品族
class MaterialButton extends Button {
render() {
return `
<button class="mdc-button mdc-button--raised" onclick="${this.clickHandler}">
<span class="mdc-button__label">${this.text}</span>
</button>
`;
}
}
class MaterialInput extends Input {
render() {
return `
<div class="mdc-text-field mdc-text-field--filled">
<span class="mdc-text-field__ripple"></span>
<input class="mdc-text-field__input" type="text"
placeholder="${this.placeholder}" value="${this.value}">
<span class="mdc-line-ripple"></span>
</div>
`;
}
}
class MaterialModal extends Modal {
render() {
return `
<div class="mdc-dialog ${this.isVisible ? 'mdc-dialog--open' : ''}" role="alertdialog">
<div class="mdc-dialog__container">
<div class="mdc-dialog__surface">
<h2 class="mdc-dialog__title">${this.title}</h2>
<div class="mdc-dialog__content">${this.content}</div>
<div class="mdc-dialog__actions">
<button type="button" class="mdc-button mdc-dialog__button">Close</button>
</div>
</div>
</div>
<div class="mdc-dialog__scrim"></div>
</div>
`;
}
}
// Bootstrap 产品族
class BootstrapButton extends Button {
render() {
return `
<button type="button" class="btn btn-primary" onclick="${this.clickHandler}">
${this.text}
</button>
`;
}
}
class BootstrapInput extends Input {
render() {
return `
<div class="form-group">
<input type="text" class="form-control"
placeholder="${this.placeholder}" value="${this.value}">
</div>
`;
}
}
class BootstrapModal extends Modal {
render() {
return `
<div class="modal fade ${this.isVisible ? 'show' : ''}" tabindex="-1" role="dialog">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title">${this.title}</h5>
<button type="button" class="close" data-dismiss="modal">
<span>×</span>
</button>
</div>
<div class="modal-body">${this.content}</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-dismiss="modal">Close</button>
</div>
</div>
</div>
</div>
`;
}
}
// Ant Design 产品族
class AntButton extends Button {
render() {
return `
<button class="ant-btn ant-btn-primary" onclick="${this.clickHandler}">
<span>${this.text}</span>
</button>
`;
}
}
class AntInput extends Input {
render() {
return `
<div class="ant-input-wrapper">
<input class="ant-input" type="text"
placeholder="${this.placeholder}" value="${this.value}">
</div>
`;
}
}
class AntModal extends Modal {
render() {
return `
<div class="ant-modal-wrap ${this.isVisible ? '' : 'ant-modal-hidden'}">
<div class="ant-modal">
<div class="ant-modal-content">
<div class="ant-modal-header">
<div class="ant-modal-title">${this.title}</div>
</div>
<div class="ant-modal-body">${this.content}</div>
<div class="ant-modal-footer">
<button class="ant-btn">Cancel</button>
<button class="ant-btn ant-btn-primary">OK</button>
</div>
</div>
</div>
<div class="ant-modal-mask"></div>
</div>
`;
}
}
// 抽象工厂
class UIFactory {
createButton(text) {
throw new Error('createButton method must be implemented');
}
createInput(placeholder) {
throw new Error('createInput method must be implemented');
}
createModal(title, content) {
throw new Error('createModal method must be implemented');
}
// 创建完整的表单
createForm(config) {
const form = {
title: config.title,
fields: [],
buttons: [],
modal: null
};
// 创建表单字段
config.fields.forEach(field => {
form.fields.push(this.createInput(field.placeholder));
});
// 创建按钮
config.buttons.forEach(button => {
form.buttons.push(this.createButton(button.text));
});
// 创建模态框(如果需要)
if (config.modal) {
form.modal = this.createModal(config.modal.title, config.modal.content);
}
return form;
}
// 获取主题信息
getThemeInfo() {
return {
name: this.constructor.name.replace('Factory', ''),
version: '1.0.0'
};
}
}
// 具体工厂
class MaterialUIFactory extends UIFactory {
createButton(text) {
return new MaterialButton(text);
}
createInput(placeholder) {
return new MaterialInput(placeholder);
}
createModal(title, content) {
return new MaterialModal(title, content);
}
}
class BootstrapUIFactory extends UIFactory {
createButton(text) {
return new BootstrapButton(text);
}
createInput(placeholder) {
return new BootstrapInput(placeholder);
}
createModal(title, content) {
return new BootstrapModal(title, content);
}
}
class AntUIFactory extends UIFactory {
createButton(text) {
return new AntButton(text);
}
createInput(placeholder) {
return new AntInput(placeholder);
}
createModal(title, content) {
return new AntModal(title, content);
}
}
// 工厂选择器
class UIFactorySelector {
constructor() {
this.factories = new Map();
this.currentTheme = 'material';
// 注册工厂
this.registerFactory('material', new MaterialUIFactory());
this.registerFactory('bootstrap', new BootstrapUIFactory());
this.registerFactory('ant', new AntUIFactory());
}
registerFactory(theme, factory) {
if (!(factory instanceof UIFactory)) {
throw new Error('Factory must be an instance of UIFactory');
}
this.factories.set(theme, factory);
return this;
}
setTheme(theme) {
if (!this.factories.has(theme)) {
throw new Error(`Unknown theme: ${theme}`);
}
this.currentTheme = theme;
return this;
}
getFactory(theme = null) {
const selectedTheme = theme || this.currentTheme;
if (!this.factories.has(selectedTheme)) {
throw new Error(`Unknown theme: ${selectedTheme}`);
}
return this.factories.get(selectedTheme);
}
createComponent(type, ...args) {
const factory = this.getFactory();
switch (type) {
case 'button':
return factory.createButton(...args);
case 'input':
return factory.createInput(...args);
case 'modal':
return factory.createModal(...args);
default:
throw new Error(`Unknown component type: ${type}`);
}
}
createForm(config, theme = null) {
const factory = this.getFactory(theme);
return factory.createForm(config);
}
getAvailableThemes() {
return Array.from(this.factories.keys());
}
getCurrentTheme() {
return this.currentTheme;
}
}
// 使用示例
console.log('=== 抽象工厂模式测试 ===');
const uiSelector = new UIFactorySelector();
// 创建Material Design风格的组件
uiSelector.setTheme('material');
const materialButton = uiSelector.createComponent('button', 'Material Button');
const materialInput = uiSelector.createComponent('input', 'Enter your name');
const materialModal = uiSelector.createComponent('modal', 'Material Modal', 'This is a material modal');
console.log('Material Button HTML:', materialButton.render());
console.log('Material Input HTML:', materialInput.render());
// 创建Bootstrap风格的组件
uiSelector.setTheme('bootstrap');
const bootstrapButton = uiSelector.createComponent('button', 'Bootstrap Button');
const bootstrapInput = uiSelector.createComponent('input', 'Enter your email');
console.log('Bootstrap Button HTML:', bootstrapButton.render());
console.log('Bootstrap Input HTML:', bootstrapInput.render());
// 创建完整的表单
const formConfig = {
title: 'User Registration',
fields: [
{ placeholder: 'Enter your name' },
{ placeholder: 'Enter your email' },
{ placeholder: 'Enter your password' }
],
buttons: [
{ text: 'Submit' },
{ text: 'Cancel' }
],
modal: {
title: 'Confirmation',
content: 'Are you sure you want to submit?'
}
};
// 使用不同主题创建表单
const materialForm = uiSelector.createForm(formConfig, 'material');
const bootstrapForm = uiSelector.createForm(formConfig, 'bootstrap');
const antForm = uiSelector.createForm(formConfig, 'ant');
console.log('Available themes:', uiSelector.getAvailableThemes());
console.log('Current theme:', uiSelector.getCurrentTheme());
// 渲染表单
console.log('Material form fields count:', materialForm.fields.length);
console.log('Bootstrap form buttons count:', bootstrapForm.buttons.length);
console.log('Ant form modal:', antForm.modal.render());抽象工厂模式的优势:
💼 实际应用:抽象工厂模式在UI框架、主题系统、跨平台开发中应用广泛,如React的不同UI组件库、移动应用的iOS/Android适配等。
通过本节JavaScript工厂模式完整指南的学习,你已经掌握:
A: 当需要根据条件创建不同类型的对象、对象创建逻辑复杂、需要隐藏对象创建细节、或者需要支持系统扩展时,应该考虑使用工厂模式。
A: 简单工厂用一个工厂类创建所有产品;工厂方法为每种产品提供专门的工厂类;抽象工厂用于创建产品族,确保产品间的一致性。
A: 工厂模式会增加一层抽象,可能带来轻微的性能开销,但这通常是可以接受的。相比直接创建对象,工厂模式提供的灵活性和可维护性更有价值。
A: 可以通过模拟工厂、注入测试工厂、或者测试具体的产品类来进行测试。工厂模式实际上有助于提高代码的可测试性。
A: 可以,工厂本身可以是单例的,确保全局只有一个工厂实例。这在需要统一管理对象创建逻辑时很有用。
// 问题:动态注册新的产品类型
// 解决:实现插件式工厂注册
class PluginFactory {
constructor() {
this.creators = new Map();
this.plugins = new Map();
}
registerPlugin(name, plugin) {
this.plugins.set(name, plugin);
if (plugin.creators) {
Object.entries(plugin.creators).forEach(([type, creator]) => {
this.creators.set(type, creator);
});
}
}
create(type, ...args) {
if (this.creators.has(type)) {
return this.creators.get(type)(...args);
}
throw new Error(`Unknown type: ${type}`);
}
}// 问题:频繁创建相同对象导致性能问题
// 解决:实现工厂缓存机制
class CachedFactory {
constructor() {
this.cache = new Map();
this.maxCacheSize = 100;
}
create(type, config) {
const cacheKey = `${type}_${JSON.stringify(config)}`;
if (this.cache.has(cacheKey)) {
return this.cache.get(cacheKey);
}
const instance = this.createInstance(type, config);
if (this.cache.size >= this.maxCacheSize) {
const firstKey = this.cache.keys().next().value;
this.cache.delete(firstKey);
}
this.cache.set(cacheKey, instance);
return instance;
}
}"掌握工厂模式,让你的代码拥有更好的扩展性和可维护性。每一个设计模式的应用,都是对代码架构的提升!"