工厂模式
工厂模式「Factory Pattern」:属于创建者模式,将模块中对象的创建和对象的使用进行分离,外界对于这些对象只需要知道它们的接口,而不需要知道其中具体的实现细节,以此来使整个系统的设计更加符合单一职责的原则。

模式动机

拿 KFC 来举例,你只需要去 KFC 告诉工作人员汉堡的名字即可拿到对应的汉堡,不需要每个来 KFC 的人都自己做汉堡,而且你也不关心汉堡是如何做的KFC 员工也不会关心你如何使用汉堡,这就实现了创建于使用的解耦。
工厂模式的存在就是为了解耦,将对象的创建和使用分离。
降低代码重复度,对象的创建过于复杂时放到工厂模式中只需要书写一次即可

简单工厂模式

简单工厂模式「Simple Factory Pattern」:又称为静态工厂方法 「Static Factory Method」模式,它属于类创建型模式。在简单工厂模式中,可以根据参数的不同返回不同类的实例。简单工厂模式专门定义一个类来负责创建其他类的实例,被创建的实例通常都具有共同的父类
1
// 汉堡工厂
2
const Hamburger = function(name) {
3
function ChickenBurger() {
4
this.name = '鸡腿堡'
5
this.price = 12
6
}
7
8
function BeefBurger() {
9
this.name = '牛肉汉堡'
10
this.price = 15
11
}
12
13
function VeggieBurger() {
14
this.name = '蔬菜汉堡'
15
this.price = 10
16
}
17
18
switch (name) {
19
case '鸡腿堡':
20
return new ChickenBurger()
21
case '牛肉汉堡':
22
return new BeefBurger()
23
case '蔬菜汉堡':
24
return new VeggieBurger()
25
default:
26
throw new Error('对不起,本店没有你想要的汉堡')
27
}
28
}
29
30
const chickenBuger = new Hamburger('鸡腿堡')
31
Copied!
ES6 实现方法
1
class Hamburger {
2
// 因为各个汉堡的结构基本相同,此处可以抽象出来
3
constructor(info) {
4
this.name = info.name
5
this.price = info.price
6
}
7
// 不会被实例继承,可以由 Hamburger 直接调用
8
static getHamburger(name) {
9
switch (name) {
10
case '鸡腿堡':
11
return new Hamburger({name: '鸡腿堡', price: 12})
12
case '牛肉汉堡':
13
return new Hamburger({name: '牛肉汉堡', price: 15})
14
case '蔬菜汉堡':
15
return new Hamburger({name: '蔬菜汉堡', price: 10})
16
default:
17
throw new Error('对不起,本店没有你想要的汉堡')
18
}
19
}
20
}
21
22
const chickenBuger = Hamburger.getHamburger('鸡腿堡')
Copied!
但是简单工厂也存在一些问题,当需要创建的对象过多或者创建对象的逻辑变得复杂的时候,工厂函数就会显得十分庞大臃肿,其复杂度将会直线提高。

工厂方法模式

工厂方法模式将实际创建对象的工作推迟到了子类中,工厂父类负责定义创建产品对象的公共接口。( 但此处并没有推迟到了子类,只是放在了原型中 )
1
const Hamburger = function(name) {
2
// this 是当前对象,则说明是用 new 创建的, 否则 this 应该是全局对象
3
if(this instanceof Hamburger) {
4
return new this[name]() // 这边将 this[name]() 就相当于 CHickenBuger() 返回对应的实例
5
} else {
6
// 如果不是用 new 创建的,就返回给他用 new 创建的 Hamburger 实例
7
return new Hamburger(name)
8
}
9
}
10
11
Hamburger.prototype = {
12
ChickenBuger: function() {
13
this.name = '鸡腿堡'
14
this.price = 12
15
},
16
BeefBuger: function() {
17
this.name = '牛肉汉堡'
18
this.price = 15
19
},
20
VeggieBurger: function() {
21
this.name = '蔬菜汉堡'
22
this.price = 10
23
}
24
}
25
26
const chickenBuger = Hamburger('ChickenBuger')
Copied!

抽象工厂模式

「抽象」就是将复杂事物的一个或多个共有特征抽取出来的思维过程。
可以看到,简单工厂与工厂方法模式都是直接返回创建的实例,但抽象工厂模式并不会直接返回创建的实例,而是用于对产品类簇的创建。也就是将各个工厂方法模式又抽象出来,找出了其中的共同特征。
抽象工厂示例

创建实体类

1
// 汉堡类产品
2
class ChickenBuger {
3
constructor() {
4
this.name = '鸡腿堡'
5
this.price = 12
6
}
7
}
8
9
class BeefBuger {
10
constructor() {
11
this.name = '牛肉堡'
12
this.price = 15
13
}
14
}
15
16
// 饮料类产品
17
18
class Cola {
19
constructor() {
20
this.name = '可乐'
21
this.price = 5
22
}
23
}
24
25
class Sprite {
26
constructor() {
27
this.name = '雪碧'
28
this.price = 5
29
}
30
}
Copied!

创建工厂类

ChickenBugerBeefBuger 同属于 Hamburger 类,ColaSprite 同属于 Drink 类。
1
class Hamburger {
2
getInstance(name) {
3
switch(name) {
4
case 'ChickenBuger':
5
return new ChickenBuger()
6
case 'BeefBuger':
7
return new BeefBuger()
8
}
9
}
10
}
11
12
class Drink {
13
getInstance(name) {
14
switch(name) {
15
case 'Cola':
16
return new Cola()
17
case 'Sprite':
18
return new Sprite()
19
}
20
}
21
}
22
Copied!

创建抽象工厂

1
class KFC {
2
constructor(type) {
3
switch(type) {
4
case 'Hamburger':
5
return new Hamburger()
6
case 'Drink':
7
return new Drink()
8
}
9
}
10
}
11
12
const HamburgerFAC = new KFC('Hamburger')
13
const chickenBuger = HamburgerFAC.getInstance('ChickenBuger')
Copied!

小结

工厂方法模式的主要优点是增加新的产品类时无须修改现有系统,并封装了产品对象的创建细节,系统具有良好的灵活性和可扩展性;其缺点在于增加新产品的同时需要增加新的工厂,导致系统类的个数成对增加,在一定程度上增加了系统的复杂性。
Last modified 2yr ago