11// cppcheck-suppress-file [functionStatic]
22
3- // Builder is a creational design pattern that lets you construct complex
4- // objects step by step. The pattern allows you to produce different types and
5- // representations of an object using the same construction code. Appicability:
6- // (*) Use the Builder pattern to get rid of a “telescoping constructor”.
7- // (**) when you want your code to be able to create different representations
8- // of some product (for example, stone and wooden houses).
9-
10- // UML: docs/uml/patterns_behavioral_iterator.drawio.svg
11-
3+ #include < memory>
124#include < ostream>
135#include < sstream>
146#include < string>
157#include < vector>
168#include " Logger.h"
179
10+ #include " ExampleRegistry.h"
11+
1812namespace {
1913namespace builder_pattern {
2014class Product {
@@ -37,10 +31,8 @@ class Product {
3731 }
3832};
3933
40- /* *
41- * The Builder interface specifies methods for creating the different parts of
42- * the Product objects.
43- */
34+ // / @class Builder Interface
35+ // / @brief specifics methods for creating the different parts
4436class IBuilder {
4537 public:
4638 virtual ~IBuilder () = default ;
@@ -49,53 +41,30 @@ class IBuilder {
4941 virtual IBuilder& produce_part_2 () = 0;
5042 virtual IBuilder& produce_part_3 () = 0;
5143
52- virtual Product* build () = 0;
44+ virtual std::unique_ptr< Product> build () = 0;
5345};
5446
5547class AbstractBuilder : public IBuilder {
5648 protected:
57- Product* product_;
49+ std::unique_ptr< Product> product_;
5850
5951 public:
60- explicit AbstractBuilder () { product_ = new Product (); }
61-
62- ~AbstractBuilder () override { delete product_; }
63-
64- AbstractBuilder (const AbstractBuilder& other) {
65-
66- delete product_;
67-
68- product_ = new Product ();
69- *product_ = *other.product_ ;
70- }
71-
72- AbstractBuilder& operator =(const AbstractBuilder& other) {
73- if (this == &other) {
74- return *this ;
75- }
52+ explicit AbstractBuilder () : product_{std::make_unique<Product>()} {}
7653
77- delete product_;
78- product_ = new Product ();
79- *product_ = *other.product_ ;
54+ AbstractBuilder (const AbstractBuilder&) = delete ;
55+ AbstractBuilder& operator =(const AbstractBuilder&) = delete ;
8056
81- return * this ;
82- }
57+ AbstractBuilder (AbstractBuilder&&) = default ;
58+ AbstractBuilder& operator =(AbstractBuilder&&) = default ;
8359
84- // the child classes are no longer override this function
60+ // / @brief the child classes are no longer override this function
8561 IBuilder& reset () final {
86-
87- delete product_;
88- product_ = new Product ();
89-
62+ product_ = std::make_unique<Product>();
9063 return *this ;
9164 }
9265};
9366
94- /* *
95- * The Concrete Builder classes follow the Builder interface and provide
96- * specific implementations of the building steps. Your program may have several
97- * variations of Builders, implemented differently.
98- */
67+ // / @class Concrete Builder
9968class SimpleBuilder : public AbstractBuilder {
10069 public:
10170 IBuilder& produce_part_1 () override {
@@ -113,7 +82,7 @@ class SimpleBuilder : public AbstractBuilder {
11382 return *this ;
11483 }
11584
116- Product* build () override { return product_; }
85+ std::unique_ptr< Product> build () override { return std::move ( product_) ; }
11786};
11887
11988class ComplexBuilder : public AbstractBuilder {
@@ -133,23 +102,25 @@ class ComplexBuilder : public AbstractBuilder {
133102 return *this ;
134103 }
135104
136- Product* build () override { return product_; }
105+ std::unique_ptr< Product> build () override { return std::move ( product_) ; }
137106};
138107
139108void run () {
140109 auto client_code = [](IBuilder* const builder) {
141- const Product* p1 =
110+ // product 1
111+ auto p1 =
142112 (*builder).produce_part_1 ().produce_part_2 ().produce_part_3 ().build ();
143113 p1->print ();
144- const Product* p2 = (*builder).reset ().produce_part_1 ().build ();
114+
115+ // product 2
116+ auto p2 = (*builder).reset ().produce_part_1 ().build ();
145117 p2->print ();
146118 };
147119
148120 {
149121 LOG (" ConcreteBuilder: Simple" );
150- IBuilder* builder = new SimpleBuilder ();
151- client_code (builder);
152- delete builder;
122+ auto builder = std::make_unique<SimpleBuilder>();
123+ client_code (builder.get ());
153124 }
154125 {
155126 LOG (" ConcreteBuilder: Complex" );
@@ -161,8 +132,6 @@ void run() {
161132} // namespace builder_pattern
162133} // namespace
163134
164- #include " ExampleRegistry.h"
165-
166135class BuilderExample : public IExample {
167136 public:
168137 std::string group () const override { return " dp/creational" ; }
0 commit comments