亲宝软件园·资讯

展开

JS工厂模式

掘金安东尼 人气:0

前言;

工厂模式(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​​​就是一个简单工厂,2个实例对应不同的权限,调用工厂函数时,只需传递 ​​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年提出,含义是“软件实体( 类、模块、函数等 )应该是可扩展的,但不可修改”。

三、抽象工厂模式

抽象工厂模式(Abstract Factory Pattern)是围绕一个超级工厂创建其他工厂。该超级工厂又称为其他工厂的工厂。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。

分分钟理解 3 种工厂模式_简单工厂模式

抽象工厂只留对外的口子,不做事,留给外界覆盖(子类重写接口方法以便创建的时候指定自己的对象类型)。主要用于对 产品类簇

的创建,不直接生成实例(简单工厂模式和工厂方法模式都是生成实例)。

比如 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');

四、小结

用大白话解释:

简单工厂模式就是你给工厂什么,工厂就给你生产什么;

工厂方法模式就是你找工厂生产产品,工厂是外包给下级分工厂来代加工,需要先评估一下能不能代加工;能做就接,不能做就找其他工厂;

抽象工厂模式就是工厂接了某项产品订单但是做不了,上级集团公司新建一个工厂来专门代加工某项产品;

再实在一点的解释:

简单工厂模式,就是你去线下小卖部买东西,你要罐头这个商品,它就会把拥有罐头属性的东西给你;

工厂方法模式,就是你去网购,你要罐头,首先网店会判断自己店里有没有这个东西,如果没有,就去进货;但是注意的是,它进货也并不是先进到店里再发给你,而是直接从进货的子工厂发给你;

抽象工厂模式,即:做出像淘宝、京东、拼夕夕这样的工厂,是一个更高级别的构建,你再去其中买罐头;

加载全部内容

相关教程
猜你喜欢
用户评论