设计模式_工厂模式

0 参考链接

链接_视频
链接_文档

1 介绍

工厂模式,Factory Pattern。

意图:创建对象时不会对客户端暴露创建逻辑,并且是通过使用一个共同的接口来只当新创建对象。定义一个创建对象的接口,让其子类自己决定实例化哪一个工厂类,工厂模式使其创建过程延迟到子类进行。
主要解决:接口选择的问题。
何时使用:我们明确地计划不同条件下创建不同实例时。
如何解决:让其子类实现工厂接口,返回的也是一个抽象的产品。
关键代码:创建过程在其子类执行。
优点:

  • 调用者想创建一个对象,只要知道其名称即可。
  • 扩展性高,如果想增加一个产品,只要扩展一个工厂类即可。
  • 屏蔽产品的具体实现,调用者只关心产品的接口。

使用场景:

  • 日志记录器,记录可能记录到本地硬盘,系统事件或远程服务器等,用户可以选择记录日志到什么地方。
  • 设计一个连接服务器的框架,需要三个协议,POP3IMAPHTTP,可以把三个作为产品类,共同实现一个接口。

Highlight:

  • 创建复杂对象适合使用工厂模式,而简单对象,特别是只需要通过new就可以完成创建的对象,无需使用工厂模式。如果使用工厂模式,就需要引入一个工厂类,增加系统的复杂度。(So, what is 复杂对象 ??)

2 实现

2.0 case_0: 子类数据成员一致

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
// 父类Color,接口类
class Color {
public:
// 关键字virtual修饰,虚函数
virtual void draw() = 0;
}

// 子类Red继承父类Color
class Red : public Color {
public:
// 关键字override修饰
void draw() override {
std::cout << "Red" << std::endl;
}
}

// 子类Green继承父类Color
class Green : public Color {
public:
// 关键字override修饰
void draw() override {
std::cout << "Green" << std::endl;
}
}

// 工厂类,生成对象
class Factory {
public:
// 关键字static修饰,定位为类的静态方法,调用时不需要有类的对象
static Color* getColor(std::string color) {
if (color == "Red") {
return new Red;
}
if (color == "Green") {
return new Green;
}

return nullptr;
}
}

int main() {
unique_ptr<Color> pRed(Factory::getColor("Red"));
unique_ptr<Color> pGreen(Factory::getColor("Green"));

if(pRed != nullptr) {
pRed->draw();
}
if(pGreen != nullptr) {
pGreen->draw();
}

return 0;
}

2.1 case_1: 子类数据成员不一致

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
// 父类Color,接口类
class Color {
public:
// 关键字virtual修饰,虚函数
virtual void draw() = 0;
}

// 子类Red继承父类Color
class Red : public Color {
public:
Red(std::string a, int b)
: a_(std::move(a)), b_(b) {
}

// 关键字override修饰
void draw() override {
std::cout << a_ << ", " << b_ << std::endl;
}

//

std::string a_;
int b_;
}

// 子类Green继承父类Color
class Green : public Color {
public:
Green(std::string a)
: a_(std::move(a)) {
}

// 关键字override修饰
void draw() override {
std::cout << a_ << std::endl;
}

std::string a_;
}

// 工厂不一定需要是类,一个函数也可以
// 泛型,模板
// 参数个数不定, typename ... Args可变参数
template<typename Object, typename ... Args>
Color* factoryColor(typename ... Args) {
return new Object(args ...);
}

int main() {
unique_ptr<Color> pRed(factoryColor("Red", 666));
unique_ptr<Color> pGreen(factoryColor("Green"));

if(pRed != nullptr) {
pRed->draw();
}
if(pGreen != nullptr) {
pGreen->draw();
}

return 0;
}
  • 版权声明: 本博客所有文章均采用 Apache License 2.0 许可协议。转载请注明出处!
  • © 2020-2021 Hang Liu
  • Powered by Hexo Theme Ayer
  • PV: UV: