-
Notifications
You must be signed in to change notification settings - Fork 5
Expand file tree
/
Copy pathabstract_factory.cpp
More file actions
113 lines (99 loc) · 3.17 KB
/
abstract_factory.cpp
File metadata and controls
113 lines (99 loc) · 3.17 KB
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
// Abstract factory design pattern
#include <iostream>
#include <memory>
// abstract product
struct IWidget {
virtual void draw() const = 0;
virtual ~IWidget() = default;
};
// concrete product
class OSXButton : public IWidget {
public:
void draw() const override { std::cout << "\tOS X Button" << '\n'; }
};
// concrete product
class OSXWindow : public IWidget {
public:
void draw() const override { std::cout << "\tOS X Window" << '\n'; }
};
// concrete product
class WinButton : public IWidget {
public:
void draw() const override { std::cout << "\tWindows Button" << '\n'; }
};
// concrete product
class WinWindow : public IWidget {
public:
void draw() const override { std::cout << "\tWindows Window" << '\n'; }
};
// abstract factory
struct IFactory {
virtual std::unique_ptr<IWidget> create_button() = 0;
virtual std::unique_ptr<IWidget> create_window() = 0;
virtual ~IFactory() = default;
};
// concrete factory
class OSXFactory : public IFactory {
public:
OSXFactory() { std::cout << "Creating the OSXFactory..." << '\n'; }
std::unique_ptr<IWidget> create_button() {
return std::make_unique<OSXButton>();
}
std::unique_ptr<IWidget> create_window() {
return std::make_unique<OSXWindow>();
}
virtual ~OSXFactory() {
std::cout << "Destroying the OSXFactory..." << '\n';
}
};
// concrete factory
class WinFactory : public IFactory {
public:
WinFactory() { std::cout << "Creating the WinFactory..." << '\n'; }
std::unique_ptr<IWidget> create_button() {
return std::make_unique<WinButton>();
}
std::unique_ptr<IWidget> create_window() {
return std::make_unique<WinWindow>();
}
virtual ~WinFactory() {
std::cout << "Destroying the WinFactory..." << '\n';
}
};
// combine Abstract factory with Strategy
class SuperFactory : public IFactory {
std::unique_ptr<IFactory> _factory;
public:
explicit SuperFactory(std::unique_ptr<IFactory> factory)
: _factory{std::move(factory)} {
std::cout << "Creating the SuperFactory..." << '\n';
}
void set_factory(std::unique_ptr<IFactory> factory) {
std::cout << "Changing the IFactory strategy" << '\n';
_factory = std::move(factory);
}
std::unique_ptr<IWidget> create_button() {
return _factory->create_button();
}
std::unique_ptr<IWidget> create_window() {
return _factory->create_window();
}
~SuperFactory() { std::cout << "Destroying the SuperFactory..." << '\n'; }
};
int main() {
// Direct usage of Abstract factory pattern
std::unique_ptr<IFactory> factory{std::make_unique<OSXFactory>()};
factory->create_button()->draw();
factory->create_window()->draw();
std::cout << "--------" << '\n';
factory = std::make_unique<WinFactory>();
factory->create_button()->draw();
factory->create_window()->draw();
std::cout << "--------" << '\n';
// Usage via the Strategy pattern
SuperFactory super_factory(std::make_unique<OSXFactory>());
super_factory.create_button()->draw();
super_factory.set_factory(std::move(factory));
super_factory.create_window()->draw();
std::cout << "--------" << '\n';
}