工厂模式

简单工厂、工厂方法、抽象工厂

简单工厂

定义与结构

简单工厂模式(Simple Factory Pattern):又称为静态工厂方法(Static Factory Method)模式,简单工厂模式中专门定义一个类来负责创建其他类的实例,被创建的实例通常都具有共同的父类。

直白地讲,简单工厂把实例化的操作单独放到一个类中,这个类就成为简单工厂类,让简单工厂类来决定应该用哪个具体子类来实例化,这样做能把客户类和具体子类的实现解耦,客户类不再需要知道有哪些子类以及应当实例化哪个子类。

简单工厂模式并不在 GoF 23 种设计模式之列,与其说其是设计模式,不如说是一种编程习惯。

简单工厂模式中包含如下角色:

  • Factory:工厂角色

    工厂角色负责实现创建所有实例的内部逻辑。

  • Product:抽象产品角色

    抽象产品角色是所创建的所有对象的父类,负责描述所有实例所共有的公共接口。

  • ConcreteProduct:具体产品角色

    具体产品角色是创建目标,所有创建的对象都充当这个角色的某个具体类的实例。

优缺点

优点:

  • 实现了对象创建和使用的分离。
  • 不需要记住具体类名,记住参数即可,减少使用者记忆量。

缺点:

  • 对工厂类职责过重,一旦不能工作,系统受到影响。
  • 增加系统中类的个数,复杂度和理解度增加。
  • 违反“开闭原则”,添加新产品需要修改工厂逻辑,工厂越来越复杂。
适用场景
  • 工厂类负责创建的对象比较少,由于创建的对象较少,不会造成工厂方法中的业务逻辑太过复杂。
  • 客户端只知道传入工厂类的参数,对于如何创建对象并不关心。
代码实现
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
#include <bits/stdc++.h>
using namespace std;

//抽象水果
class AbstractFruit {
public:
virtual void ShowName() = 0;
};

//苹果
class Apple :public AbstractFruit {
public:
virtual void ShowName() {
cout << "我是苹果!" << endl;
}
};

//香蕉
class Banana :public AbstractFruit {
public:
virtual void ShowName() {
cout << "我是香蕉!" << endl;
}
};

//鸭梨
class Pear :public AbstractFruit {
public:
virtual void ShowName() {
cout << "我是鸭梨!" << endl;
}
};

//水果工厂
class FruitFactor {
public:
static AbstractFruit * CreateFruit(string flag) {
if (flag == "apple") {
return new Apple;
}
else if (flag == "banana") {
return new Banana;
}
else if (flag == "pear") {
return new Pear;
}
else {
return NULL;
}
}
};

void test01() {
FruitFactor* factory = new FruitFactor;
AbstractFruit* fruit = factory->CreateFruit("apple");
fruit->ShowName();
delete fruit;

fruit = factory->CreateFruit("banana");
fruit->ShowName();
delete fruit;

fruit = factory->CreateFruit("pear");
fruit->ShowName();
delete fruit;

fruit = NULL;
delete factory;
factory = NULL;
}

int main(){
test01();
return 0;
}

工厂方法

定义与结构

工厂方法模式(Factory Method Pattern)又称为工厂模式,也叫虚拟构造器(Virtual Constructor)模式或者多态工厂(Polymorphic Factory)模式,它属于类创建型模式。在工厂方法模式中,工厂父类负责定义创建产品对象的公共接口,而工厂子类则负责生成具体的产品对象,这样做的目的是将产品类的实例化操作延迟到工厂子类中完成,即通过工厂子类来确定究竟应该实例化哪一个具体产品类。

直白地讲,“工厂方法模式”是对简单工厂模式的进一步抽象化,只是工厂方法把产品的实例化操作推迟到子类。

工厂方法模式由4个要素构成:

  • 抽象工厂(Abstract Factory):提供了创建产品的接口,调用者通过它访问具体工厂的工厂方法 createProduct() 来创建产品。
  • 具体工厂(ConcreteFactory):主要是实现抽象工厂中的抽象方法,完成具体产品的创建。
  • 抽象产品(Product):定义了产品的规范,描述了产品的主要特性和功能。
  • 具体产品(ConcreteProduct):实现了抽象产品角色所定义的接口,由具体工厂来创建,它同具体工厂之间一一对应。
优缺点

优点

  • 用户只需要关心所需产品对应的工厂,无须关心创建细节,甚至无须知道具体产品类的类名。
  • 灵活性增强,对于新产品的创建,只需多写一个相应的工厂类。
  • 典型的解耦框架。高层模块只需要知道产品的抽象类,无须关心其他实现类,满足迪米特法则、依赖倒置原则和里氏替换原则。

缺点

  • 类的个数容易过多,增加复杂度。
  • 考虑到系统的可扩展性,需要引入抽象层,在客户端代码中均使用抽象层进行定义,增加了系统的抽象性和理解难度。
  • 抽象产品只能生产一种产品。
适用场景

在工厂方法模式中,客户端不需知道具体产品类的类名,只需知道创建具体产品的工厂类;对于抽象工厂抽象工厂类,只需要提供一个创建产品的接口,而由其子类来确定具体要创建的对象。

代码实现
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
88
89
90
91
92
93
94
95
96
97
98
99
#include <bits/stdc++.h>
using namespace std;

//抽象水果
class AbstractFruit {
public:
virtual void ShowName() = 0;
};

//苹果
class Apple :public AbstractFruit {
public:
virtual void ShowName() {
cout << "我是苹果!" << endl;
}
};

//香蕉
class Banana :public AbstractFruit {
public:
virtual void ShowName() {
cout << "我是香蕉!" << endl;
}
};

//鸭梨
class Pear :public AbstractFruit {
public:
virtual void ShowName() {
cout << "我是鸭梨!" << endl;
}
};

//抽象工厂
class AbstractFruitFactory {
public:
virtual AbstractFruit* CreateFruit() = 0;
};


//苹果工厂
class AppleFactory :public AbstractFruitFactory {
public:
virtual AbstractFruit* CreateFruit() {
return new Apple;
}
};

//香蕉工厂
class BananaFactory :public AbstractFruitFactory {
public:
virtual AbstractFruit* CreateFruit() {
return new Banana;
}
};

//鸭梨工厂
class PearFactory :public AbstractFruitFactory {
public:
virtual AbstractFruit* CreateFruit() {
return new Pear;
}
};


void test01() {
AbstractFruitFactory* factory = NULL;
AbstractFruit* fruit = NULL;

//创建一个苹果工厂
factory = new AppleFactory;
fruit = factory->CreateFruit();
fruit->ShowName();
delete fruit;
delete factory;

//创建一个香蕉工厂
factory = new BananaFactory;
fruit = factory->CreateFruit();
fruit->ShowName();
delete fruit;
delete factory;

//创建一个鸭梨工厂
factory = new PearFactory;
fruit = factory->CreateFruit();
fruit->ShowName();
delete fruit;
delete factory;
fruit = NULL;
factory = NULL;

}

int main() {
test01();
return 0;
}

抽象工厂

问题引出

为了更清晰地理解工厂方法模式,先理解两个概念:

  • 产品等级 :产品等级结构即产品的继承结构,如一个抽象类是电视机,其子类有海尔电视机、海信电视机、TCL电视机,则抽象电视机与具体品牌的电视机之间构成了一个产品等级结构,抽象电视机是父类,而具体品牌的电视机是其子类。

  • 产品族 :在抽象工厂模式中,产品族是指由同一个工厂生产的,位于不同产品等级结构中的一组产品,如海尔电器工厂生产的海尔电视机、海尔电冰箱,海尔电视机位于电视机产品等级结构中,海尔电冰箱位于电冰箱产品等级结构中。

    产品结构

定义与结构

抽象工厂模式(Abstract Factory Pattern):提供一个接口,用于创建创建一系列相关或相互依赖对象的家族,而无须指定它们具体的类。抽象工厂模式又称为Kit模式,属于对象创建型模式。

抽象工厂模式与工厂方法模式区别在于,工厂方法模式针对的是一个产品等级结构,而抽象工厂模式则需要面对多个产品等级结构,一个工厂等级结构可以负责多个不同产品等级结构中的产品对象的创建 。

抽象工厂模式同工厂方法模式一样,也是由4 个要素构成,但抽象工厂中方法个数不同,抽象产品的个数也不同。

  • AbstractFactory:抽象工厂
  • ConcreteFactory:具体工厂
  • AbstractProduct:抽象产品
  • Product:具体产品
优缺点

优点

  • 抽象工厂模式隔离了具体类的生成,使得客户并不需要知道什么被创建,从具体的产品解耦出来。
  • 当一个产品族中的多个对象被设计成一起工作时,它能够保证客户端始终只使用同一个产品族中的对象。
  • 增加新的具体工厂和产品族很方便,无须修改已有系统,符合“开闭原则”。

缺点

  • 开闭原则的倾斜性(增加新的工厂和产品族容易,增加新的产品等级结构麻烦)
适用场景
  • 系统中有多于一个的产品族。而每次只使用其中某一产品族。可以通过配置文件等方式来使得用户可以动态改变产品族,也可以很方便地增加新的产品族。
  • 产品等级结构稳定。设计完成之后,不会向系统中增加新的产品等级结构或者删除已有的产品等级结构
代码实现
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
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
#include <bits/stdc++.h>
using namespace std;

//抽象苹果
class AbstractApple {
public:
virtual void ShowName() = 0;
};

//中国苹果
class ChinaApple :public AbstractApple {
public:
virtual void ShowName() {
cout << "中国苹果!" << endl;
}
};

//美国苹果
class USAApple :public AbstractApple {
public:
virtual void ShowName() {
cout << "美国苹果!" << endl;
}
};

//日本苹果
class JapanApple :public AbstractApple {
public:
virtual void ShowName() {
cout << "日本苹果!" << endl;
}
};

//抽象香蕉
class AbstractBanana {
public:
virtual void ShowName() = 0;
};

//中国香蕉
class ChinaBanana :public AbstractBanana {
public:
virtual void ShowName() {
cout << "中国香蕉!" << endl;
}
};

//美国香蕉
class USABanan :public AbstractBanana {
public:
virtual void ShowName() {
cout << "美国香蕉!" << endl;
}
};

//日本香蕉
class JapanBanan :public AbstractBanana {
public:
virtual void ShowName() {
cout << "日本香蕉!" << endl;
}
};

//抽象鸭梨
class AbstractPear {
public:
virtual void ShowName() = 0;
};


//中国鸭梨
class ChinaPear:public AbstractPear{
public:
virtual void ShowName() {
cout << "中国鸭梨!" << endl;
}
};

//美国鸭梨
class USAPear :public AbstractPear {
public:
virtual void ShowName() {
cout << "美国鸭梨!" << endl;
}
};

//日本鸭梨
class JapanPear :public AbstractPear {
public:
virtual void ShowName() {
cout << "日本鸭梨!" << endl;
}
};


//抽象工厂 针对产品族
class AbstractFactory {
public:
virtual AbstractApple* CreateApple() = 0;
virtual AbstractBanana* CreateBanana() = 0;
virtual AbstractPear* CreatePear() = 0;
};

//中国工厂
class ChinaFactory :public AbstractFactory {
public:
virtual AbstractApple* CreateApple() {
return new ChinaApple;
}
virtual AbstractBanana* CreateBanana(){
return new ChinaBanana;
}
virtual AbstractPear* CreatePear() {
return new ChinaPear;
}
};

//美国工厂
class USAFactory :public AbstractFactory {
public:
virtual AbstractApple* CreateApple() {
return new USAApple;
}
virtual AbstractBanana* CreateBanana() {
return new USABanan;
}
virtual AbstractPear* CreatePear() {
return new USAPear;
}
};

//日本工厂
class JapanFactory :public AbstractFactory {
public:
virtual AbstractApple* CreateApple() {
return new JapanApple;
}
virtual AbstractBanana* CreateBanana() {
return new JapanBanan;
}
virtual AbstractPear* CreatePear() {
return new JapanPear;
}
};

void test01() {
AbstractFactory* factory = NULL;
AbstractApple* apple = NULL;
AbstractBanana* banana = NULL;
AbstractPear* pear = NULL;

//中国工厂
factory = new ChinaFactory;
apple = factory->CreateApple();
banana = factory->CreateBanana();
pear = factory->CreatePear();

apple->ShowName();
banana->ShowName();
pear->ShowName();
}

int main() {
test01();
return 0;
}

-------------本文结束 感谢阅读-------------
0%