1//! @file creational.hpp
2//! @author ryftchen
3//! @brief The declarations (creational) in the design pattern module.
4//! @version 0.1.0
5//! @copyright Copyright (c) 2022-2026 ryftchen. All rights reserved.
6
7#pragma once
8
9#include <array>
10#include <memory>
11#include <sstream>
12
13//! @brief The design pattern module.
14namespace design_pattern // NOLINT(modernize-concat-nested-namespaces)
15{
16//! @brief Creational-related functions in the design pattern module.
17namespace creational
18{
19//! @brief Brief function description.
20//! @return function description (module_function)
21inline static const char* description() noexcept
22{
23 return "DP_CREATIONAL";
24}
25extern const char* version() noexcept;
26
27//! @brief The abstract factory pattern.
28namespace abstract_factory
29{
30//! @brief Implement the same interface. The others can refer to the interface not the concrete product.
31class ProductA
32{
33public:
34 //! @brief Destroy the ProductA object.
35 virtual ~ProductA() = default;
36
37 //! @brief Get the product name.
38 //! @return product name
39 [[nodiscard]] virtual std::string getName() const = 0;
40};
41
42//! @brief The concrete product.
43class ConcreteProductAX : public ProductA
44{
45public:
46 //! @brief Get the product name.
47 //! @return product name
48 [[nodiscard]] std::string getName() const override;
49};
50
51//! @brief The concrete product.
52class ConcreteProductAY : public ProductA
53{
54public:
55 //! @brief Get the product name.
56 //! @return product name
57 [[nodiscard]] std::string getName() const override;
58};
59
60//! @brief Implement the same interface. The others can refer to the interface not the concrete product.
61class ProductB
62{
63public:
64 //! @brief Destroy the ProductB object.
65 virtual ~ProductB() = default;
66
67 //! @brief Get the product name.
68 //! @return product name
69 [[nodiscard]] virtual std::string getName() const = 0;
70};
71
72//! @brief The concrete product.
73class ConcreteProductBX : public ProductB
74{
75public:
76 //! @brief Get the product name.
77 //! @return product name
78 [[nodiscard]] std::string getName() const override;
79};
80
81//! @brief The concrete product.
82class ConcreteProductBY : public ProductB
83{
84public:
85 //! @brief Get the product name.
86 //! @return product name
87 [[nodiscard]] std::string getName() const override;
88};
89
90//! @brief Provide the abstract interface for creating the family of products.
91//! It never has to instantiate a product object.
92class AbstractFactory
93{
94public:
95 //! @brief Destroy the AbstractFactory object.
96 virtual ~AbstractFactory() = default;
97
98 //! @brief Create product A.
99 //! @return product A
100 virtual std::unique_ptr<ProductA> createProductA() = 0;
101 //! @brief Create product B.
102 //! @return product B
103 virtual std::unique_ptr<ProductB> createProductB() = 0;
104};
105
106//! @brief The concrete factory.
107class ConcreteFactoryX : public AbstractFactory
108{
109public:
110 //! @brief Create product A.
111 //! @return product A
112 std::unique_ptr<ProductA> createProductA() override;
113 //! @brief Create product B.
114 //! @return product B
115 std::unique_ptr<ProductB> createProductB() override;
116};
117
118//! @brief The concrete factory.
119class ConcreteFactoryY : public AbstractFactory
120{
121public:
122 //! @brief Create product A.
123 //! @return product A
124 std::unique_ptr<ProductA> createProductA() override;
125 //! @brief Create product B.
126 //! @return product B
127 std::unique_ptr<ProductB> createProductB() override;
128};
129
130extern std::ostringstream& output() noexcept;
131} // namespace abstract_factory
132
133//! @brief The builder pattern.
134namespace builder
135{
136//! @brief Product properties.
137class Product
138{
139public:
140 //! @brief Make part A.
141 //! @param part - target part
142 void makeA(const std::string_view part);
143 //! @brief Make part B.
144 //! @param part - target part
145 void makeB(const std::string_view part);
146 //! @brief Make part C.
147 //! @param part - target part
148 void makeC(const std::string_view part);
149 //! @brief Get all parts.
150 //! @return all parts
151 [[nodiscard]] std::string get() const;
152
153private:
154 //! @brief Part A.
155 std::string partA;
156 //! @brief Part B.
157 std::string partB;
158 //! @brief Part C.
159 std::string partC;
160};
161
162//! @brief The builder for creating products.
163class Builder
164{
165public:
166 //! @brief Destroy the Builder object.
167 virtual ~Builder() = default;
168
169 //! @brief Get the product.
170 //! @return product
171 [[nodiscard]] Product get() const;
172 //! @brief Build part A.
173 virtual void buildPartA() = 0;
174 //! @brief Build part B.
175 virtual void buildPartB() = 0;
176 //! @brief Build part C.
177 virtual void buildPartC() = 0;
178
179protected:
180 //! @brief The product.
181 Product product{};
182};
183
184//! @brief The concrete builder.
185class ConcreteBuilderX : public Builder
186{
187public:
188 //! @brief Build part A.
189 void buildPartA() override;
190 //! @brief Build part B.
191 void buildPartB() override;
192 //! @brief Build part C.
193 void buildPartC() override;
194};
195
196//! @brief The concrete builder.
197class ConcreteBuilderY : public Builder
198{
199public:
200 //! @brief Build part A.
201 void buildPartA() override;
202 //! @brief Build part B.
203 void buildPartB() override;
204 //! @brief Build part C.
205 void buildPartC() override;
206};
207
208//! @brief Manage the correct sequence of creation.
209class Director
210{
211public:
212 //! @brief Set the builder.
213 //! @param b - target builder
214 void set(std::unique_ptr<Builder> b);
215 //! @brief Get the product from the builder.
216 //! @return product
217 [[nodiscard]] Product get() const;
218 //! @brief Construct products by the builder.
219 void construct();
220
221private:
222 //! @brief The builder.
223 std::unique_ptr<Builder> builder;
224};
225
226extern std::ostringstream& output() noexcept;
227} // namespace builder
228
229//! @brief The factory method pattern.
230namespace factory_method
231{
232//! @brief Implement the same interface. The others can refer to the interface not the concrete product.
233class Product
234{
235public:
236 //! @brief Destroy the Product object.
237 virtual ~Product() = default;
238
239 //! @brief Get the product name.
240 //! @return product name
241 [[nodiscard]] virtual std::string getName() const = 0;
242};
243
244//! @brief The concrete product.
245class ConcreteProductA : public Product
246{
247public:
248 //! @brief Get the product name.
249 //! @return product name
250 [[nodiscard]] std::string getName() const override;
251};
252
253//! @brief The concrete product.
254class ConcreteProductB : public Product
255{
256public:
257 //! @brief Get the product name.
258 //! @return product name
259 [[nodiscard]] std::string getName() const override;
260};
261
262//! @brief Contain the implementation for all methods to manipulate products except for the factory method.
263//! Know how to create the products.
264class Creator
265{
266public:
267 //! @brief Destroy the Creator object.
268 virtual ~Creator() = default;
269
270 //! @brief Create product A.
271 //! @return product A
272 virtual std::unique_ptr<Product> createProductA() = 0;
273 //! @brief Create product B.
274 //! @return product B
275 virtual std::unique_ptr<Product> createProductB() = 0;
276 //! @brief Remove product.
277 virtual void removeProduct(std::unique_ptr<Product>& product) = 0;
278};
279
280//! @brief The concrete creator.
281class ConcreteCreator : public Creator
282{
283public:
284 //! @brief Create product A.
285 //! @return product A
286 std::unique_ptr<Product> createProductA() override;
287 //! @brief Create product B.
288 //! @return product B
289 std::unique_ptr<Product> createProductB() override;
290 //! @brief Remove product.
291 void removeProduct(std::unique_ptr<Product>& product) override;
292};
293
294extern std::ostringstream& output() noexcept;
295} // namespace factory_method
296
297//! @brief The prototype pattern.
298namespace prototype
299{
300//! @brief The interface for cloning itself.
301class Prototype
302{
303public:
304 //! @brief Destroy the Prototype object.
305 virtual ~Prototype() = default;
306
307 //! @brief Clone self.
308 //! @return cloning of self
309 virtual std::unique_ptr<Prototype> clone() = 0;
310 //! @brief Get the type.
311 //! @return type
312 [[nodiscard]] virtual std::string type() const = 0;
313};
314
315//! @brief The concrete prototype.
316class ConcretePrototypeA : public Prototype
317{
318public:
319 //! @brief Clone self.
320 //! @return cloning of self
321 std::unique_ptr<Prototype> clone() override;
322 //! @brief Get the type.
323 //! @return type
324 [[nodiscard]] std::string type() const override;
325};
326
327//! @brief The concrete prototype.
328class ConcretePrototypeB : public Prototype
329{
330public:
331 //! @brief Clone self.
332 //! @return cloning of self
333 std::unique_ptr<Prototype> clone() override;
334 //! @brief Get the type.
335 //! @return type
336 [[nodiscard]] std::string type() const override;
337};
338
339//! @brief Create by asking the prototype to clone itself.
340class Client
341{
342public:
343 //! @brief Initialize all prototypes.
344 static void init();
345 //! @brief Remove all prototypes.
346 static void remove();
347 //! @brief Make by prototype index.
348 //! @param index - prototype index
349 //! @return cloning result
350 static std::unique_ptr<Prototype> make(const int index);
351
352private:
353 //! @brief Collection of prototypes.
354 static std::array<std::unique_ptr<Prototype>, 2> types;
355 //! @brief Number of types.
356 static const int nTypes;
357};
358
359extern std::ostringstream& output() noexcept;
360} // namespace prototype
361
362//! @brief The singleton factory pattern.
363namespace singleton
364{
365//! @brief Have a private static variable to hold one instance of the singleton.
366//! It gives a way to instantiate the singleton.
367class Singleton
368{
369public:
370 //! @brief Destroy the Memento object.
371 virtual ~Singleton() = default;
372 //! @brief Construct a new Singleton object.
373 Singleton(const Singleton&) = delete;
374 //! @brief Construct a new Singleton object.
375 Singleton(Singleton&&) = delete;
376 //! @brief The operator (=) overloading of Singleton class.
377 //! @return reference of the Singleton object
378 Singleton& operator=(const Singleton&) = delete;
379 //! @brief The operator (=) overloading of Singleton class.
380 //! @return reference of the Singleton object
381 Singleton& operator=(Singleton&&) = delete;
382
383 //! @brief Get the instance of the singleton.
384 //! @return instance of the singleton
385 static std::shared_ptr<Singleton> get();
386 //! @brief Restart the instance of the singleton.
387 static void restart();
388 //! @brief Tell external.
389 void tell() const;
390
391private:
392 //! @brief Construct a new Singleton object.
393 Singleton() = default;
394
395 //! @brief The instance of the singleton.
396 static std::shared_ptr<Singleton> instance;
397};
398
399extern std::ostringstream& output() noexcept;
400} // namespace singleton
401} // namespace creational
402} // namespace design_pattern
403