简单工厂模式定义
简单工厂模式(Simple Factory Pattern
)它属于类创建型模式。在简单工厂模式中,可以根据参数的不同返回不同类的实例。简单工厂模式专门定义一个类来负责创建其他类的实例,被创建的实例通常都具有共同的父类。
简单工厂模式由来
一个汽车工厂可以生产不同品牌的汽车(奔驰、宝马等),那么汽车都源自同一个基类,不过在继承基类后不同的子类修改了部分属性从而使得他们可以生产不同品牌的汽车,如果我们希望在生产这些汽车时,不需要知道这些汽车具体的名字,只需要知道表示该汽车的一个参数,并提供一个调用方便的方法,把该参数传入方法即可生产相对应的汽车,这种情况就可以使用简单工厂模式。
简单工厂模式结构
-
Factory:工厂角色
工厂角色负责实现创建所有实例的内部逻辑
-
Product:抽象产品角色
抽象产品角色是所创建的所有对象的父类,负责描述所有实例所共有的公共接口
-
ConcreteProduct:具体产品角色
具体产品角色是创建目标,所有创建的对象都充当这个角色的某个具体类的实例。
案例分析
一个汽车工厂可以生产不同品牌的汽车(奔驰、宝马等),我们来看下两种方案的设计。
方案一:初始设计
我们采用最简单的方式就是创建一个汽车工厂类,根据参数不同生产对应的汽车即可,步骤如下:
1、创建工厂类
1
2
3
4
5
6
7
8
9
10
11
12
class CarFactory {
// 生产汽车
void produce(String type) {
if (type == "BenZ") {
// 生产细节......
print('生产了奔驰汽车');
} else if (type == "BMW") {
// 生产细节......
print("生产了宝马汽车");
}
}
}
2、使用
1
2
3
4
5
6
7
void main(List<String> args) {
CarFactory benZ = CarFactory();
benZ.produce("BenZ");
CarFactory bmw = CarFactory();
bmw.produce("BMW");
}
3、运行结果
1
2
3
4
Connecting to VM Service at http://127.0.0.1:49301/Rxk8vVrRPoE=/
生产了奔驰汽车
生产了宝马汽车
Exited
4、完整代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
void main(List<String> args) {
CarFactory benZ = CarFactory();
benZ.produce("BenZ");
CarFactory bmw = CarFactory();
bmw.produce("BMW");
}
class CarFactory {
void produce(String type) {
if (type == "BenZ") {
// 生产细节......
print('生产了奔驰汽车');
} else if (type == "BMW") {
// 生产细节......
print("生产了宝马汽车");
}
}
}
5、分析
我们通过创建一个汽车工厂类并根据对应类型就实现了生产对应品牌汽车,但是有几处问题所在,代码冗余量太大、扩展性不好、违背了开闭原则。
方案二:简单工厂模式
我们采用简单工厂模式对方案一进行优化,总共有三个角色:工厂角色、抽象产品角色、具体产品角色
1、抽象产品角色
暴露产品的接口,比如汽车可以运行
1
2
3
4
abstract class ICar {
// 汽车运行
void run();
}
2、具体产品角色
实现抽象产品角色,生产对应可运行的汽车
1
2
3
4
5
6
7
8
9
10
11
12
13
class BenZ implements ICar {
@override
void run() {
print("奔驰汽车运行");
}
}
class Bmw implements ICar {
@override
void run() {
print('宝马汽车运行');
}
}
3、工厂角色
负责生产车辆,但不暴露内部逻辑
1
2
3
4
5
6
7
8
9
10
11
12
13
// 汽车工厂
class CarFactory {
ICar createCar(String type) {
if (type == "BenZ") {
print("生产奔驰");
return BenZ()..run();
} else if (type == "BMW") {
print("生产宝马");
return Bmw()..run();
}
return BenZ()..run();
}
}
4、使用
1
2
3
4
5
6
7
void main(List<String> args) {
CarFactory benZ = CarFactory();
benZ.createCar("BenZ");
CarFactory bmw = CarFactory();
bmw.createCar("BMW");
}
5、运行结果
1
2
3
4
5
6
Connecting to VM Service at http://127.0.0.1:51086/zHTwIrAlFNg=/
生产奔驰,
奔驰汽车运行
生产宝马,
宝马汽车运行
Exited
6、完整代码
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
void main(List<String> args) {
CarFactory benZ = CarFactory();
benZ.createCar("BenZ");
CarFactory bmw = CarFactory();
bmw.createCar("BMW");
}
abstract class ICar {
// 汽车运行
void run();
}
class BenZ implements ICar {
@override
void run() {
print("奔驰汽车运行");
}
}
class Bmw implements ICar {
@override
void run() {
print('宝马汽车运行');
}
}
// 汽车工厂
class CarFactory {
ICar createCar(String type) {
if (type == "BenZ") {
print("生产奔驰");
return BenZ()..run();
} else if (type == "BMW") {
print("生产宝马");
return Bmw()..run();
}
return BenZ()..run();
}
}
7、分析
采用简单工厂模式相对于方案一有了具体角色的概念,对实例化过程进行了抽象,创建对象过程分离,对责任进行了分割。
总结
简单工厂模式优点
- 工厂类决定创建哪一个产品类的实力,客户端无需创建产品对象的责任,实现对责任的分割。
- 客户端无需知道创建具体产品类的类名,只需要知道对应参数即可。
- 通过配置文件方式,可以无需修改客户端代码更换或增加新的具体产品类,提高系统灵活性。
简单工厂模式缺点
- 工厂类是所有产品的创建逻辑,一旦出错将导致整个系统收到影响。
- 增加具体产品类在一定程度上增加了系统的复杂度和理解难度。
- 系统扩展困难,新增产品类需修改工厂逻辑,违背开闭原则