1.痛点
eg:A类中实例化B类。若是B的构造函数发生更改,若是b引用次数不少。
2.利
构造方法代替new,
减小冗余代码。缓存
3.分类iphone
简单工厂模式函数
class SampleFactory { constructor(opt) { this.role = opt.role; this.permissions = opt.permissions; } // 静态方法 static create(role) { switch (role) { case 'admin': return new SampleFactory({ role: '管理员', permissions: ['设置', '删除', '新增', '建立', '开发', '推送', '提问', '评论'] }); break; case 'developer': return new SampleFactory({ 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();
- 1.简单工厂函数适用场景 * 正确传参,就能够获取所须要的对象,无需知道内部实现细节; * 内部逻辑(工厂函数)经过传入参数判断实例化仍是使用哪些类; * 建立对象数量少(稳定),对象的建立逻辑不复杂; 2.简单工厂函数不适用场景 * 当须要添加新的类时,就须要修改工厂方法,这违背了开放封闭原则(OCP, 对扩展开放、对源码修改封闭)。正所谓成也萧何败也萧何。函数 `create` 内包含了全部建立对象(构造函数)的判断逻辑代码,若是要增长新的构造函数还须要修改函数 `create`(判断逻辑代码),当可选参数 `role` 变得更多时,那函数 `create` 的判断逻辑代码就变得臃肿起来,难以维护。 * 不适用建立多类对象
将实际建立对象工做推迟到子类当中,核心类就成了抽象类。这样添加新的类时就无需修改工厂方法,只须要将子类注册进工厂方法的原型对象中便可。this
// 0.0.2/function.factory.js class FunctionFactoryBase { // 抽象类 constructor(role) { if (new.target === FunctionFactoryBase) { throw new Error('抽象类不能实例'); } this.role = role; } } class FunctionFactory extends FunctionFactoryBase { // 子类 constructor(role) { super(role); } static create(role) { switch (role) { case 'admin': return new FunctionFactory({ role: '管理员', permissions: ['设置', '删除', '新增', '建立', '开发', '推送', '提问', '评论'] }); break; case 'developer': return new FunctionFactory({ role: '开发者', permissions: ['开发', '推送', '提问', '评论'] }); break; default: throw new Error('参数只能为 admin 或 developer'); } } show() { const { role, permissions } = this.role; const str = `是一个${role}, 权限:${permissions.join(', ')}`; console.log(str) } } // let xl = new FunctionFactoryBase(); // 此行会报错,注释后方可正常执行后面 let xm = FunctionFactory.create('admin'); xm.show() let xh = FunctionFactory.create('developer'); xh.show() let xl = FunctionFactory.create('guest'); xl.show()
抽象工厂只留对外的口子,不作事,留给外界覆盖(子类重写接口方法以便建立的时候指定本身的对象类型)。主要用于对产品类簇的建立,不直接生成实例(简单工厂模式和工厂方法模式都是生成实例)。prototype
function AbstractFactory(subType, superType) { if (typeof AbstractFactory[superType] === 'function') { //缓存类 function F() { } //继承父类属性和方法 F.prototype = new AbstractFactory[superType](); //将子类 constructor 指向子类(本身) subType.prototype.constructor = subType; //子类原型继承缓存类(父类) subType.prototype = new F(); } else { //不存在该抽象类抛出错误 throw new Error('抽象类不存在') } AbstractFactory.Phone = function () { this.type = 'Phone'; } AbstractFactory.Phone.prototype = { showType: function () { return new Error('Phone 抽象方法 showType 不能调用'); }, showPrice: function () { return new Error('Phone 抽象方法 showPrice 不能调用'); }, showColor: function () { return new Error('Phone 抽象方法 showColor 不能调用'); } } AbstractFactory.Pad = function () { this.type = 'Pad'; } AbstractFactory.Pad.prototype = { showType: function () { return new Error('Pad 抽象方法 showType 不能调用'); }, showPrice: function () { return new Error('Pad 抽象方法 showPrice 不能调用'); }, showColor: function () { return new Error('Pad 抽象方法 showColor 不能调用'); } } function Iphone(type, price, color) { this.type = type; this.price = price; this.color = color; } AbstractFactory(Iphone, 'Phone'); Iphone.prototype.showType = function () { return this.type; } Iphone.prototype.showPrice = function () { return this.price; } Iphone.prototype.showColor = function () { return this.color; } function Ipad(type, price, color) { this.type = type; this.price = price; this.color = color; } AbstractFactory(Ipad, 'Pad'); Ipad.prototype.showType = function () { return this.type; } Ipad.prototype.showPrice = function () { return this.price; } Ipad.prototype.showColor = function () { return this.color; } var iphone5s = new Iphone('iphone 5s', 3000, '白色'); console.log('今天刚买了' + iphone5s.showType() + ',价格是' + iphone5s.showPrice() + ',' + iphone5s.showColor()) var iphone8s = new Iphone('iphone 8s', 8000, '白色'); console.log('今天刚买了' + iphone8s.showType() + ',价格是' + iphone8s.showPrice() + ',' + iphone8s.showColor()) var ipad = new Ipad('ipad air', 2000, '骚红色'); console.log('今天刚买了' + ipad.showType() + ',价格是' + ipad.showPrice() + ',' + ipad.showColor())