工厂模式
用来创建对象的一种最常用的设计模式,不会暴漏创建对象的具体逻辑,而是将逻辑封装在一个函数中,这个函数就是一个工厂
工厂模式又包含了三种模式:简单工厂模式 、 工厂方法模式、抽象工厂模式。
(1)简单工厂模式(类似于:一个工厂生产多件商品)
例子:根据传入的身份,来显示不同的职业工作(传入的身份不同,那么就显示不同的工作)
function Factory(career){
function Work(career,task){
this.career =carerr
this.tast =task
}
let task
switch(career){
case 'code':
task=['写代码','修bug']
return Work(career,task)
break
case 'hr':
task=['面试新人','谈薪资']
return Work(career,task)
break
}
}
let hr =new Factory('hr')
console.log(hr)
let code =new Factory('code')
console.log(code)
优点:简单工厂顾名思义,实现比较简单,只需要传入特定参数即可
缺点: 违背了开闭原则(也就是一旦要增加新的产品,就要修改工厂类)
(2)工厂方法模式(类似于:多个工厂,但每个工厂只生产一个特定的商品)
例子:同样是根据身份,来生成不同的工作任务
function Factory(career){
// 这个是为了解决 对类创建的错误使用
if(this instanceof Factory){
var a =new this[career]()
return a
}
else{
return new Factory(career)
}
}
// 在原型上,设置构造函数
Factoyr.prototype={
'code':function(){
this.task=['写代码']
this.career='程序员'
},
'hr':function(){
this.task=['面试新人']
this.career='HR'
}
}
let hr =new Factory('hr')
console.log(hr)
优点:符合开闭原则
缺点:每次新增产品,产品类都需要创建对应的工厂类
(3)抽象工厂模式(类似于:一个工厂可以生产多类产品,A工厂可以生产A品牌的自行车、摩托车,B工厂可以生产B品牌的自行车,摩托车)
/* 工厂 抽象类 */
class AbstractFactory {
constructor() {
if (new.target === AbstractFactory)
throw new Error('抽象类不能直接实例化!')
}
/* 抽象方法 */
createProduct1() { throw new Error('抽象方法不能调用!') }
}
/* 具体饭店类 */
class Factory extends AbstractFactory {
constructor() { super() }
createProduct1(type) {
switch (type) {
case 'Product1':
return new Product1()
case 'Product2':
return new Product2()
default:
throw new Error('当前没有这个产品 -。-')
}
}
}
/* 抽象产品类 */
class AbstractProduct {
constructor() {
if (new.target === AbstractProduct)
throw new Error('抽象类不能直接实例化!')
this.kind = '抽象产品类1'
}
/* 抽象方法 */
operate() { throw new Error('抽象方法不能调用!') }
}
/* 具体产品类1 */
class Product1 extends AbstractProduct {
constructor() {
super()
this.type = 'Product1'
}
operate() { console.log(this.kind + ' - ' + this.type) }
}
/* 具体产品类2 */
class Product2 extends AbstractProduct {
constructor() {
super()
this.type = 'Product2'
}
operate() { console.log(this.kind + ' - ' + this.type) }
}
const factory = new Factory()
const prod1 = factory.createProduct1('Product1')
prod1.operate() // 输出: 抽象产品类1 - Product1
const prod2 = factory.createProduct1('Product3')
优点:隔离了具体类的生成(客户端并不需要知道其什么时候被创建的)
缺点:扩展是非常费力的,要修改很多的类