设计模式之工厂模式

定义

工厂模式类似于现实生活中的工厂可以产生大量相似的商品,去做同样的事情,实现同样的效果;

简单工厂

简单工厂模式又叫静态工厂模式,由一个工厂对象决定创建某一种产品对象类的实例。主要用来创建同一类对象

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
 
class Car {
//构造器
constructor(opt) {
this.name = opt.name;
this.type = opt.type;
this.size = opt.size;
}

//静态方法
static getInstance(role) {
switch (type) {
case '小面':
return new Car({ name: '小面', type:1,width:10,height:10 });
break;
case '金杯':
return new Car({ name: '金杯', type:2,width:20,height:20 });
break;
case '厢货':
return new Car({ name: '厢货', type:3,width:30,height:30 });
break;
default:
throw new Error('参数错误, 可选参数:小面、金杯、厢货')
}
}
}

//调用
let xm = Car.getInstance('小面');
let jb = Car.getInstance('金杯');
let xh = User.getInstance('厢货');

Car就是一个简单工厂,在该函数中有3个实例中分别对应不同的车型的汽车。当我们调用工厂函数时,只需要传递汽车的名称就可以获取对应的实例对象。

简单工厂的优点在于,你只需要一个正确的参数,就可以获取到你所需要的对象,而无需知道其创建的具体细节。但是在函数内包含了所有对象的创建逻辑(构造函数)和判断逻辑的代码,每增加新的构造函数还需要修改判断逻辑代码。当我们的对象不是上面的3个而是30个或更多时,这个函数会成为一个庞大的超级函数,便得难以维护。所以,简单工厂只能作用于创建的对象数量有限,对象的创建逻辑不复杂,并且外界无需直接设定对象的具体参数的场景。

缺点

每次增加一个产品时,都需要增加一个具体类和对象实现工厂,使得系统中类的个数成倍增加,在一定程度上增加了系统的复杂度,同时也增加了系统具体类的依赖。这并不是什么好事。

抽象工厂

简单工厂模式是直接生成实例,但是抽象工厂模式不同,抽象工厂模式并不直接生成实例, 而是用于对产品类簇的创建。

例如上面车型的例子,业务升级,除了自营车队,又需要扩展加盟车队,这时我们就需要定义统一的标准方便接入。可以对车型抽象。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
 
class standardCar {
constructor() {
if (new.target === standardCar) {
throw new Error('不能实例化抽象类')
}
}
get name(){
return "名称"
}
get size(){ // 车型尺寸
return {width:100,height:100}
}
get price(){ // 每公里价格
return 10
}
}

class jinbei extends standardCar {
constructor() {
}
get name(){
return "金杯"
}
get size(){ // 车型尺寸
return {width:200,height:300}
}
get price(){ // 每公里价格
return 100
}
}

class xiaomian extends standardCar {
constructor() {
}
get name(){
return "小面"
}
get size(){ // 车型尺寸
return {width:50,height:60}
}
get price(){ // 每公里价格
return 100
}
}

class xianghuo extends standardCar {
constructor() {
}
get name(){
return "厢货"
}
get size(){ // 车型尺寸
return {width:50,height:60}
}
get price(){ // 每公里价格
return 100
}
}

//调用

class carFactory {
//构造器
//静态方法
static getInstance(role) {
switch (type) {
case '小面':
return new xiaomian();
break;
case '金杯':
return new jinbei();
break;
case '金杯':
return new xianghuo();
break;
default:
throw new Error('参数错误, 可选参数:小面、金杯、厢货')
}
}
}



let xm = carFactory.getInstance('小面');
let jb = carFactory.getInstance('金杯');
let xh = carFactory.getInstance('厢货');

缺点

产品族扩展非常困难,要增加一个系列的某一产品,既要在抽象的 Creator 里加代码,又要在具体的里面加代码。

实战场景

多端兼容处理

同样的方法根据不同端做出不同响应。简单方式在业务代码中通过 if else 判断执行对应的方法,造成业务混乱不易阅读。此时可以尝试工厂模式。

源码

vue动态组件

动态组件

参考

类介绍

打赏
  • 版权声明: 本博客所有文章除特别声明外,均采用 Apache License 2.0 许可协议。转载请注明出处!

请我喝杯咖啡吧~

支付宝
微信