本文深入解析 JavaScript 中的三种创建型设计模式:简单工厂、工厂方法与抽象工厂。通过 ES5 与 ES6 代码示例,阐述各模式的实现原理、适用场景及优缺点,并借助生活类比帮助理解其核心差异与最佳实践。
前言
工厂模式(Factory Pattern)是软件开发中应用最为广泛的设计模式之一。
该模式归属于创建型设计模式范畴,旨在提供一种优化对象创建过程的机制。
在工厂模式的应用中,对象的创建逻辑对客户端隐藏,客户端通过统一的接口来引用新创建的对象实例。
工厂模式主要包含以下三种形式:
- 简单工厂模式
- 工厂方法模式
- 抽象工厂模式
一、简单工厂模式
简单工厂模式,亦称静态工厂模式,其核心在于利用一个工厂类来实例化同一类别的对象。
具体示例如下:
// 0.0.2/es5.simple.factory.js
function Role(options){
this.role = options.role;
this.permissions = options.permissions;
}
Role.prototype.show = function (){
var str = '是一个' + this.role + ', 权限:' + this.permissions.join(', ');
console.log(str)
}
function simpleFactory(role){
switch(role) {
case 'admin':
return new Role({
role: '管理员',
permissions: ['设置', '删除', '新增', '创建', '开发', '推送', '提问', '评论']
});
break;
case 'developer':
return new Role({
role: '开发者',
permissions: ['开发', '推送', '提问', '评论']
});
break;
default:
throw new Error('参数只能为 admin 或 developer');
}
}
// 实例
const xm = simpleFactory('admin');
xm.show();
const xh = simpleFactory('developer');
xh.show();
const xl = simpleFactory('guest');
xl.show();ES6 实现方式:
// 0.0.2/simple.factory.js
class SimpleFactory {
constructor(opt) {
this.role = opt.role;
this.permissions = opt.permissions;
}
// 静态方法
static create(role) {
switch (role) {
case 'admin':
return new SimpleFactory({
role: '管理员',
permissions: ['设置', '删除', '新增', '创建', '开发', '推送', '提问', '评论']
});
break;
case 'developer':
return new SimpleFactory({
role: '开发者',
permissions: ['开发', '推送', '提问', '评论']
});
break;
default:
throw new Error('参数只能为 admin 或 developer');
}
}
show() {
const str = `是一个${this.role}, 权限:${this.permissions.join(', ')}`;
console.log(str);
}
}
// 实例
const xm = SampleFactory.create('admin');
xm.show();
const xh = SampleFactory.create('developer');
xh.show();
const xl = SampleFactory.create('guest');
xl.show();在上述示例中,simpleFactory 构成了一个简单工厂。两个不同的实例分别对应不同的权限角色,调用工厂函数时,仅需传入 admin 或 developer 即可获取相应的对象实例。
需要注意的是,虽然工厂模式适用于生成复杂对象的场景,但对于仅需通过 new 关键字即可创建的简单对象,使用工厂模式反而会增加系统的复杂度,因为需要额外引入一个工厂类。因此,简单对象无需使用此模式。
二、工厂方法模式
该模式将具体的对象创建工作延迟到子类中执行,核心类则退化为抽象类。
这种设计使得在添加新类时无需修改现有的工厂方法,只需将新子类注册到工厂方法的原型对象中即可实现扩展。
示例代码如下:
// 0.0.2/es5.function.factory.js
function FunctionFactory(role) {
if(!(['admin', 'developer'].indexOf(role) > -1)){
throw new Error('参数只能为 admin 或 developer');
}
// 安全的工厂方法
if (this instanceof FunctionFactory) {
return this[role]();
}
return new FunctionFactory(role);
}
FunctionFactory.prototype.show = function () {
var str = '是一个' + this.role + ', 权限:' + this.permissions.join(', ');
console.log(str)
}
FunctionFactory.prototype.admin = function (permissions) {
this.role = '管理员';
this.permissions = ['设置', '删除', '新增', '创建', '开发', '推送', '提问', '评论'];
}
FunctionFactory.prototype.developer = function (permissions) {
this.role = '开发者';
this.permissions = ['开发', '推送', '提问', '评论'];
}
var xm = FunctionFactory('admin');
xm.show();
var xh = FunctionFactory('developer');
xh.show();
var xl = FunctionFactory('guest');
xl.show();当需要新增类时,只需将其挂载到 FunctionFactory.prototype 上。
这种方式无需修改原有的工厂方法,从而实现了 OCP 原则。
OCP(Open-Closed Principle,开放-封闭原则)由 Bertrand Meyer 于 1988 年提出,其核心思想是“软件实体(类、模块、函数等)应当对扩展开放,对修改封闭”。
- “可扩展”(Open for extension)意味着软件模块的功能和行为是可以变化和扩展的。
- “不可修改”(Closed for modifications)指在扩展新功能时,无需改动原有代码模块,而是通过增加新代码来实现。
三、抽象工厂模式
抽象工厂模式(Abstract Factory Pattern)围绕一个超级工厂来创建其他工厂,该超级工厂也被称为工厂的工厂。作为一种创建型模式,它提供了创建对象的最佳实践方式。

抽象工厂仅对外提供接口而不执行具体操作,留给子类进行覆盖(即子类重写接口方法以在创建时指定自己的对象类型)。它主要用于产品类簇的创建,而非直接生成实例(简单工厂和工厂方法模式均直接生成实例)。
例如 jQuery 的实现:
图示说明:
// 0.0.2/jquery.factory.js
// 工厂模式
class jQuery {
constructor(selector) {
let slice = Array.prototype.slice;
let dom = slice.call(document.querySelectorAll(selector));
let len = dom ? dom.length : 0;
for (let i = 0; i < len; i++) {
this[i] = dom[i];
}
this.length = len
this.selector = selector || ''
}
addClass(name) {
console.log(name)
}
html(data) {
}
// 省略多个 API
}
// 工厂模式
window.$ = function(selector) {
return new jQuery(selector);
}
// 实例
const $li = $('li')
$li.addClass('item');四、小结
用通俗语言解释:
简单工厂模式即你给工厂什么原料,工厂就生产什么产品;
工厂方法模式即你委托工厂生产产品,工厂将任务外包给下级分工厂加工,需先评估其加工能力;能做则接,不能做则寻找其他工厂;
抽象工厂模式即工厂接到某项产品订单但无法独立完成,由上级集团公司新建一个专门工厂来代工该项产品;
更直观的生活化解释:
简单工厂模式好比你去线下小卖部购买罐头,你指定要罐头商品,小卖部就提供具有罐头属性的物品给你;
工厂方法模式好比网购,你要买罐头,网店首先判断店内是否有货;若无货,则进行进货。但值得注意的是,进货并非先存入店铺再发货,而是直接从子工厂发往你手中;
抽象工厂模式即构建如淘宝、京东、拼多多这样的高级平台,你在此类平台上购买罐头;
本文关于 JavaScript 三种工厂模式用法的介绍到此结束,更多相关 JS 工厂模式内容请搜索本站以前的文章或继续浏览下面的相关文章,希望大家以后多多支持本站!