工厂模式

设计模式之一

使用场景

  • 我们不会直接在客户端代码中暴露对象的创建逻辑,而是通过一个共同的接口来创建对象。

  • 从而将对象的创建过程与具体的实现用客户端代码分离开来。

细分

  1. 简单工厂模式(Simple Factory Pattern)
  • 简单工厂模式也称为静态工厂模式,它通过一个专门的工厂类来创建对象,而无需将对象的实例化过程放在客户端代码中。

  • 简单工厂模式定义了一个创建对象的接口,但创建逻辑是放在同一个工厂类中的。客户端通过调用工厂类的静态方法来获取所需的对象。

    • 优点:客户端代码与具体产品的耦合度降低,易于添加新的产品类型(尽管这可能需要修改工厂类的代码,违反了开闭原则)。

    • 缺点:当产品类型增多时,工厂类的代码可能会变得复杂。

  1. 工厂方法模式(Factory Method Pattern)
  • 工厂方法模式定义了一个创建对象的接口,但让子类决定实例化哪个类。这样可以将对象的创建与使用解耦,使得系统在不修改具体产品类的情况下可以引入新的产品。

  • 工厂方法模式在抽象工厂类中定义了一个创建产品的接口,但具体的创建逻辑由具体工厂类实现。客户端通过调用具体工厂类的工厂方法来创建产品对象。

    • 优点:客户端只需要关心抽象产品和抽象工厂,具体产品的创建由具体工厂类来完成,符合开闭原则。

    • 缺点:增加了系统的复杂性,需要为每个产品创建一个工厂类。

  1. 抽象工厂模式(Abstract Factory Pattern)
  • 抽象工厂模式提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类。它能够创建多个系列的产品,而不是单一产品。

  • 抽象工厂模式定义了一个创建对象的接口,但接口内部可以创建多个相互关联或依赖的对象。客户端通过调用抽象工厂接口来获取一系列相关对象。

    • 优点:分离了具体类的生成,符合开闭原则;提供了一个一致的产品族创建方式。

    • 缺点:增加了系统的抽象性和复杂性。

1. 简单工厂模式(Simple Factory)

简单工厂模式通过一个工厂类来创建不同类的对象,根据传入的参数决定实例化哪一个类。

示例:

假设我们有一个产品接口 Product,以及两个具体产品类 ConcreteProductAConcreteProductB

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

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

// 具体产品A
class ConcreteProductA : public Product {
public:
void use() override {
std::cout << "Using ConcreteProductA" << std::endl;
}
};

// 具体产品B
class ConcreteProductB : public Product {
public:
void use() override {
std::cout << "Using ConcreteProductB" << std::endl;
}
};

// 简单工厂类
class SimpleFactory {
public:
static std::unique_ptr<Product> createProduct(const std::string& type) {
if (type == "A") {
return std::make_unique<ConcreteProductA>();
} else if (type == "B") {
return std::make_unique<ConcreteProductB>();
}
return nullptr;
}
};

int main() {
auto productA = SimpleFactory::createProduct("A");
productA->use();

auto productB = SimpleFactory::createProduct("B");
productB->use();

return 0;
}

2. 工厂方法模式(Factory Method)

工厂方法模式定义了一个创建对象的接口,但由子类决定要实例化的类是哪一个。工厂方法让类的实例化推迟到子类中进行。

示例:

假设我们有一个抽象产品 Product 和两个具体产品 ConcreteProductAConcreteProductB,以及对应的工厂接口 Factory 和其实现 ConcreteFactoryAConcreteFactoryB

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 ~Product() = default;
virtual void use() = 0;
};

// 具体产品A
class ConcreteProductA : public Product {
public:
void use() override {
std::cout << "Using ConcreteProductA" << std::endl;
}
};

// 具体产品B
class ConcreteProductB : public Product {
public:
void use() override {
std::cout << "Using ConcreteProductB" << std::endl;
}
};

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

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

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

int main() {
auto factoryA = std::make_unique<ConcreteFactoryA>();
auto productA = factoryA->createProduct();
productA->use();

auto factoryB = std::make_unique<ConcreteFactoryB>();
auto productB = factoryB->createProduct();
productB->use();

return 0;
}

3. 抽象工厂模式(Abstract Factory)

抽象工厂模式提供一个接口,用于创建相关或依赖对象的家族,而不需要明确指定具体类。

示例:

假设我们有两套产品族,一套是 ButtonWindow,每套产品族有两个具体实现:WindowsButtonWindowsWindowMacButtonMacWindow

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

// 抽象产品Button
class Button {
public:
virtual ~Button() = default;
virtual void paint() = 0;
};

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

// 具体产品WindowsButton
class WindowsButton : public Button {
public:
void paint() override {
std::cout << "Painting a Windows button" << std::endl;
}
};

// 具体产品WindowsWindow
class WindowsWindow : public Window {
public:
void display() override {
std::cout << "Displaying a Windows window" << std::endl;
}
};

// 具体产品MacButton
class MacButton : public Button {
public:
void paint() override {
std::cout << "Painting a Mac button" << std::endl;
}
};

// 具体产品MacWindow
class MacWindow : public Window {
public:
void display() override {
std::cout << "Displaying a Mac window" << std::endl;
}
};

// 抽象工厂接口
class AbstractFactory {
public:
virtual ~AbstractFactory() = default;
virtual std::unique_ptr<Button> createButton() = 0;
virtual std::unique_ptr<Window> createWindow() = 0;
};

// 具体工厂WindowsFactory
class WindowsFactory : public AbstractFactory {
public:
std::unique_ptr<Button> createButton() override {
return std::make_unique<WindowsButton>();
}
std::unique_ptr<Window> createWindow() override {
return std::make_unique<WindowsWindow>();
}
};

// 具体工厂MacFactory
class MacFactory : public AbstractFactory {
public:
std::unique_ptr<Button> createButton() override {
return std::make_unique<MacButton>();
}
std::unique_ptr<Window> createWindow() override {
return std::make_unique<MacWindow>();
}
};

int main() {
auto windowsFactory = std::make_unique<WindowsFactory>();
auto windowsButton = windowsFactory->createButton();
auto windowsWindow = windowsFactory->createWindow();
windowsButton->paint();
windowsWindow->display();

auto macFactory = std::make_unique<MacFactory>();
auto macButton = macFactory->createButton();
auto macWindow = macFactory->createWindow();
macButton->paint();
macWindow->display();

return 0;
}

工厂模式
https://weihehe.top/2024/09/14/工厂模式/
作者
weihehe
发布于
2024年9月14日
许可协议