-
Notifications
You must be signed in to change notification settings - Fork 4
Expand file tree
/
Copy pathRealWorldFactoryMethod.cpp
More file actions
204 lines (154 loc) · 5.96 KB
/
Copy pathRealWorldFactoryMethod.cpp
File metadata and controls
204 lines (154 loc) · 5.96 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
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
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
// ===========================================================================
// RealWorldFactoryMethod.cpp // Factory Method
// ===========================================================================
#include <memory>
#include <print>
#include <string>
namespace RealWorldFactoryMethod {
// interface declares the methods that all concrete products must implement
class ITelevision
{
public:
virtual ~ITelevision() {}
virtual std::string getManufacturer() const = 0;
virtual void switchOn() = 0;
virtual void switchOff() = 0;
};
// concrete Products provide various implementations of the ITelevision interface
class LEDTelevision : public ITelevision
{
public:
std::string getManufacturer() const final {
return "LED TV";
}
void switchOn() override {
std::println("Switched on my LED TV");
};
void switchOff() override {
std::println("Switched on my LED TV");
};
};
class OledTelevision : public ITelevision
{
public:
std::string getManufacturer() const final {
return "Oled TV";
}
void switchOn() override {
std::println("Switched on my OLED TV");
};
void switchOff() override {
std::println("Switched off my OLED TV");
};
};
// ---------------------------------------------------------------------------
class AbstractTVFactory
{
/**
* Note that the FactoryBase's class primary responsibility is not only creating products.
* Usually, it contains some core business logic that relies on concrete product objects,
* returned by the factory method.
*
* Subclasses can indirectly change that business logic by overriding the factory method and
* returning a different type of product from it.
*/
// Protected Interface: protected virtual methods
// these methods have to be provided by concrete factory classes.
// These methods are NOT seen by any client
protected:
virtual bool manufactureTelevision() = 0; // take order, create order number, create invoice
virtual std::unique_ptr<ITelevision> assembleTelevision() = 0; // produce concrete television device
virtual float shippingCharge() const = 0;
virtual float productionCharge() const = 0;
public:
virtual ~AbstractTVFactory() {}
// Public Interface:
// These methods are available for clients
// Three so called "Factory Methods" do exist in this example
std::unique_ptr<ITelevision> orderTV() {
if (manufactureTelevision()) { // <= abstract method (!)
// Note: client receives 'ITelevision' pointer
std::unique_ptr<ITelevision> tvup{ assembleTelevision() }; // <= abstract method (!)
return tvup;
}
// concrete factory cannot produce this tv currently
std::unique_ptr<ITelevision> empty{};
return empty;
}
void getOrderInformation() {
float costsOfShippingCharge{ shippingCharge() }; // <= abstract method (!)
std::println("Shipping charge: {} Euro", costsOfShippingCharge);
float costsOfProduction{ productionCharge() }; // <= abstract method (!)
std::println("Production charge: {} Euro", costsOfProduction);
}
float totalCharge() {
float total{
shippingCharge() + // <= abstract method (!)
productionCharge() // <= abstract method (!)
};
return total;
}
};
class LEDTVFactory : public AbstractTVFactory
{
protected:
bool manufactureTelevision() override {
std::println("Manufacturing LED TV");
return true;
}
std::unique_ptr<ITelevision> assembleTelevision() override {
std::println("Assembling LED TV");
return std::make_unique<LEDTelevision>();
}
float shippingCharge() const override {
return 1000.0F;
}
float productionCharge() const override {
return 1500.0F;
}
};
class OledTVFactory : public AbstractTVFactory {
protected:
bool manufactureTelevision() override {
std::println("Manufacturing Oled TV");
return true;
}
std::unique_ptr<ITelevision> assembleTelevision() override {
std::println("Assembling Oled TV");
return std::make_unique<OledTelevision>();
}
float shippingCharge() const override {
return 2000.0F;
}
float productionCharge() const override {
return 2500.0F;
}
};
static void clientCode(const std::shared_ptr<AbstractTVFactory>& factory) {
factory->getOrderInformation();
std::println("My new television receiver costs me {} ", factory->totalCharge());
std::unique_ptr<ITelevision> tvPtr{ factory->orderTV() };
if (tvPtr != nullptr) {
tvPtr->switchOn();
std::println("My new TV is a {} device.", tvPtr->getManufacturer());
}
}
}
void test_real_world_example_televisions() {
using namespace RealWorldFactoryMethod;
std::println("Example launched with the LEDTVFactory.");
std::shared_ptr<AbstractTVFactory> ledFactory{
std::make_shared<LEDTVFactory>()
};
clientCode(ledFactory);
std::println();
std::println("Example launched with the OledTVFactory.");
std::shared_ptr<AbstractTVFactory> oledFactory{
std::make_shared<OledTVFactory>()
};
std::println();
clientCode(oledFactory);
}
// ===========================================================================
// End-of-File
// ===========================================================================