工厂模式

简单工厂模式

一个具体的工厂类和继承一个抽象产品类的多个产品类,通过 if 或者 switch 语句来判断生成哪个具体的产品类:

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
#include <iostream>
#include <memory>

// 产品接口
class Product {
public:
virtual void doSomething() = 0;
virtual ~Product() = default;
};

// 具体产品 A
class ProductA : public Product {
public:
void doSomething() override {
std::cout << "ProductA is doing something!" << std::endl;
}
};

// 具体产品 B
class ProductB : public Product {
public:
void doSomething() override {
std::cout << "ProductB is doing something!" << std::endl;
}
};

// 工厂类
class Factory {
public:
// 根据不同的条件创建不同的产品
static std::unique_ptr<Product> createProduct(int type) {
if (type == 1) {
return std::make_unique<ProductA>();
} else if (type == 2) {
return std::make_unique<ProductB>();
} else {
return nullptr; // 这里可以抛出异常,或者返回一个默认产品
}
}
};

int main() {
// 使用工厂创建不同的产品
auto productA = Factory::createProduct(1);
productA->doSomething(); // 输出: ProductA is doing something!

auto productB = Factory::createProduct(2);
productB->doSomething(); // 输出: ProductB is doing something!

return 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
55
56
57
58
59
60
#include <iostream>
#include <memory>

// 产品接口
class Product {
public:
virtual void doSomething() = 0;
virtual ~Product() = default;
};

// 具体产品 A
class ProductA : public Product {
public:
void doSomething() override {
std::cout << "ProductA is doing something!" << std::endl;
}
};

// 具体产品 B
class ProductB : public Product {
public:
void doSomething() override {
std::cout << "ProductB is doing something!" << std::endl;
}
};

// 工厂接口
class Factory {
public:
virtual std::unique_ptr<Product> createProduct() = 0;
virtual ~Factory() = default;
};

// 具体工厂 A
class FactoryA : public Factory {
public:
std::unique_ptr<Product> createProduct() override {
return std::make_unique<ProductA>();
}
};

// 具体工厂 B
class FactoryB : public Factory {
public:
std::unique_ptr<Product> createProduct() override {
return std::make_unique<ProductB>();
}
};

int main() {
std::unique_ptr<Factory> factoryA = std::make_unique<FactoryA>();
auto productA = factoryA->createProduct();
productA->doSomething(); // 输出: ProductA is doing something!

std::unique_ptr<Factory> factoryB = std::make_unique<FactoryB>();
auto productB = factoryB->createProduct();
productB->doSomething(); // 输出: ProductB is doing something!

return 0;
}

抽象工厂模式

你会发现,我们前面的产品是一个一个具体的,而不是一个大类。如果按照工厂方式模式来看,华为手机,苹果手机,N95 口罩,KN90 口罩。就会有四个产品类,这个四个产品类继承一个产品基类;就会有四个工厂类,这四个工厂类继承一个工厂基类。

那么抽象工厂对此进行扩展,把不同的产品类抽象为一个大类,比方说华为手机和苹果手机抽象为一个手机类,N95 口罩 和 KN90 口罩 抽象为一个口罩类。不同的工厂类会生产这两个不同类中的一个具体的类对象,比方说 FactoryB 生产华为手机和 KN90 口罩,FactoryA 生产苹果手机和 K95 口罩。

抽象工厂模式.png

代码如下:

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
// 抽象产品:手机
class Phone {
public:
virtual void call() = 0;
virtual ~Phone() = default;
};

// 抽象产品:电视机
class TV {
public:
virtual void display() = 0;
virtual ~TV() = default;
};

// 具体产品:智能手机
class SmartPhone : public Phone {
public:
void call() override {
std::cout << "SmartPhone is making a call." << std::endl;
}
};

// 具体产品:功能手机
class FeaturePhone : public Phone {
public:
void call() override {
std::cout << "FeaturePhone is making a call." << std::endl;
}
};

// 具体产品:LED电视
class LEDTV : public TV {
public:
void display() override {
std::cout << "LEDTV is displaying content." << std::endl;
}
};

// 具体产品:OLED电视
class OLEDTv : public TV {
public:
void display() override {
std::cout << "OLEDTv is displaying content." << std::endl;
}
};

class AbstractFactory {
public:
virtual std::unique_ptr<Phone> createPhone() = 0;
virtual std::unique_ptr<TV> createTV() = 0;
virtual ~AbstractFactory() = default;
};


// 具体工厂:工厂1,生产智能手机和LED电视
class Factory1 : public AbstractFactory {
public:
std::unique_ptr<Phone> createPhone() override {
return std::make_unique<SmartPhone>();
}

std::unique_ptr<TV> createTV() override {
return std::make_unique<LEDTV>();
}
};

// 具体工厂:工厂2,生产功能手机和OLED电视
class Factory2 : public AbstractFactory {
public:
std::unique_ptr<Phone> createPhone() override {
return std::make_unique<FeaturePhone>();
}

std::unique_ptr<TV> createTV() override {
return std::make_unique<OLEDTv>();
}
};

int main() {
// 使用工厂1
std::unique_ptr<AbstractFactory> factory1 = std::make_unique<Factory1>();
auto phone1 = factory1->createPhone();
auto tv1 = factory1->createTV();
phone1->call();
tv1->display();

// 使用工厂2
std::unique_ptr<AbstractFactory> factory2 = std::make_unique<Factory2>();
auto phone2 = factory2->createPhone();
auto tv2 = factory2->createTV();
phone2->call();
tv2->display();

return 0;
}

其实你会发现一个有趣的事情,如果我们的抽象工厂模式如果只生产一类产品的话,比方说只生产手机类,那么抽象工厂就退化为工厂方式模式,因为我们没有不同的类的产品,只有一类产品,那就是手机。

总结

特性 简单工厂模式 工厂方法模式 抽象工厂模式
主要目标 简化对象创建 将对象创建的职责分配给子类工厂 创建一系列相关的产品
产品数量 产品较少且变化不频繁 可以创建不同的产品 创建一组相关的产品
工厂类数量 只有一个工厂类 每个产品类有一个对应的工厂 每个产品系列有一个对应的工厂
是否符合开闭原则 不符合(需要修改工厂类) 符合(可以通过增加工厂扩展) 符合(可以通过增加工厂扩展)
适用场景 产品种类较少且变化不频繁 产品种类多且希望不同类有不同的创建方法 需要创建一系列相关的产品

这三种工厂模式的选择主要取决于产品的复杂度和变化的需求。简单工厂适用于较简单的情况,工厂方法适用于产品种类较多并且希望扩展产品类型的场景,而抽象工厂适用于需要创建多个相关产品的场景。