Skip to content

Commit 0c37b0d

Browse files
authored
Merge pull request #27 from urboob21/dev_branch
id 1764306783
2 parents 0c09633 + 24e98af commit 0c37b0d

17 files changed

+344
-85
lines changed

CMakeLists.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,9 @@ set(APP_SOURCES
111111
"src/patterns/behavioral/Observer.cpp"
112112
"src/patterns/creational/Singleton.cpp"
113113
"src/patterns/creational/FactoryMethod.cpp"
114+
"src/patterns/creational/AbstractFactory.cpp"
114115
"src/patterns/creational/Builder.cpp"
116+
"src/patterns/creational/Prototype.cpp"
115117
)
116118

117119
# Test files

docs/uml/patterns_creational_abstractfactory.drawio.svg

Lines changed: 4 additions & 0 deletions
Loading

docs/uml/patterns_creational_factorymethod.drawio.svg

Lines changed: 1 addition & 1 deletion
Loading

docs/uml/patterns_creational_prototype.drawio.svg

Lines changed: 4 additions & 0 deletions
Loading

src/core/datatypes/class/CConstructors.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -302,8 +302,8 @@ void constructers() {
302302
}
303303
} // namespace Move
304304

305-
struct CConstructorsAutoRuner {
306-
CConstructorsAutoRuner() {
305+
struct CConstructorsAutoRunner {
306+
CConstructorsAutoRunner() {
307307
InitializerList::constructers();
308308
Default::constructers();
309309
Delegate::constructors();
@@ -312,4 +312,4 @@ struct CConstructorsAutoRuner {
312312
}
313313
};
314314

315-
static CConstructorsAutoRuner instance;
315+
static CConstructorsAutoRunner instance;

src/core/datatypes/class/CDestructors.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -57,11 +57,11 @@ void destructers() {
5757
}
5858
} // namespace Virtual
5959

60-
struct CDestructorsAutoRuner {
61-
CDestructorsAutoRuner() {
60+
struct CDestructorsAutoRunner {
61+
CDestructorsAutoRunner() {
6262
Basic::destructers();
6363
Virtual::destructers();
6464
}
6565
};
6666

67-
static CDestructorsAutoRuner instance;
67+
static CDestructorsAutoRunner instance;

src/core/datatypes/class/RoleOfThreeFiveZero.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -171,7 +171,7 @@ class Model {
171171
// noexcept is a specifier that indicates a function will not throw
172172
// exceptions.
173173
Model(Model&& other) noexcept
174-
: cstring(std::exchange(other.cstring, nullptr)){};
174+
: cstring(std::exchange(other.cstring, nullptr)) {};
175175

176176
// V. move assignment
177177
Model& operator=(Model&& other) noexcept {
@@ -271,14 +271,14 @@ void run() {
271271
}
272272
} // namespace RoleOfZero
273273
} // namespace
274-
struct RoleOfThreeFiveZeroAutoRuner {
274+
struct RoleOfThreeFiveZeroAutoRunner {
275275
// Virtual default destructor: Does not break Rule of Three, Five, or Zero
276-
RoleOfThreeFiveZeroAutoRuner() {
276+
RoleOfThreeFiveZeroAutoRunner() {
277277
Problem::run();
278278
RoleOfThree::run();
279279
RoleOfFive::run();
280280
RoleOfZero::run();
281281
}
282282
};
283283

284-
static RoleOfThreeFiveZeroAutoRuner instance;
284+
static RoleOfThreeFiveZeroAutoRunner instance;

src/patterns/creational/AbstractFactory.cpp

Lines changed: 158 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -4,24 +4,170 @@
44
// families of related objects without specifying their concrete classes.
55
// Appicability:
66
// (*) when your code needs to work with various families of related products,
7-
// but you don’t want it to depend on the concrete classes
7+
// but you don’t want it to depend on the concrete classes
88
// of those products—they might be unknown beforehand or you simply want to
99
// allow for future extensibility.
1010
// (**) when you have a class with a set of Factory Methods that blur its
11-
// primary responsibility.
11+
// primary responsibility.
1212

13-
// UML: docs/uml/patterns_behavioral_iterator.drawio.svg
13+
// UML: docs/uml/patterns_creational_abstractfactory.drawio.svg
1414

1515
#include <iostream>
16+
#include <string>
17+
namespace {
18+
namespace AbstractFactory {
19+
/**
20+
* The Product interface declares the operations that all concrete products must
21+
* implement.
22+
*/
23+
class IGdbProduct {
24+
public:
25+
virtual ~IGdbProduct() = default;
26+
virtual void launch() const = 0;
27+
};
1628

17-
namespace {}
29+
/**
30+
* Concrete Products provide various implementations of the Product interface.
31+
*/
32+
class LinuxGdbProduct : public IGdbProduct {
33+
public:
34+
void launch() const override {
35+
std::cout
36+
<< "\tsudo apt update && sudo apt install -y gdb && gdb --version\n";
37+
}
38+
};
1839

19-
// struct SingletonAutoRuner
20-
// {
21-
// SingletonAutoRuner()
22-
// {
23-
// std::cout << "\n--- Singleton Pattern Example ---\n";
24-
// }
25-
// };
40+
class WindowsGdbProduct : public IGdbProduct {
41+
public:
42+
void launch() const override {
43+
std::cout << "\tpacman -Syu mingw-w64-x86_64-gdb && gdb --version\n";
44+
}
45+
};
2646

27-
// static SingletonAutoRuner instance;
47+
class MacOsGdbProduct : public IGdbProduct {
48+
public:
49+
void launch() const override {
50+
std::cout << "\tbrew install gdb && gdb --version\n";
51+
}
52+
};
53+
54+
class ICMakeProduct {
55+
public:
56+
virtual ~ICMakeProduct() = default;
57+
virtual void launch() const = 0;
58+
};
59+
60+
class LinuxCMakeProduct : public ICMakeProduct {
61+
public:
62+
void launch() const override {
63+
std::cout << "\tsudo apt update && sudo apt install -y cmake && cmake "
64+
"--version\n";
65+
}
66+
};
67+
68+
class WindowsCMakeProduct : public ICMakeProduct {
69+
public:
70+
void launch() const override {
71+
std::cout << "\tpacman -Syu cmake && cmake --version\n";
72+
}
73+
};
74+
75+
class MacOsCMakeProduct : public ICMakeProduct {
76+
public:
77+
void launch() const override {
78+
std::cout << "\tbrew install cmake && cmake --version\n";
79+
}
80+
};
81+
82+
// ===================================================================================
83+
84+
/*
85+
* Abstract Factory
86+
* provides an abstract interface for creating a family of products
87+
*/
88+
class IProductAbstractFactory {
89+
public:
90+
virtual ~IProductAbstractFactory() = default;
91+
virtual IGdbProduct* createGdbProduct() = 0;
92+
virtual ICMakeProduct* createCMakeProduct() = 0;
93+
};
94+
95+
/*
96+
* Concrete Factory
97+
* each concrete factory create a family of products and client uses
98+
* one of these factories so it never has to instantiate a product object
99+
*/
100+
class WindowsProductFactory : public IProductAbstractFactory {
101+
public:
102+
IGdbProduct* createGdbProduct() override { return new WindowsGdbProduct(); }
103+
ICMakeProduct* createCMakeProduct() override {
104+
return new WindowsCMakeProduct();
105+
}
106+
};
107+
108+
class LinuxProductFactory : public IProductAbstractFactory {
109+
public:
110+
IGdbProduct* createGdbProduct() override { return new LinuxGdbProduct(); }
111+
ICMakeProduct* createCMakeProduct() override {
112+
return new LinuxCMakeProduct();
113+
}
114+
};
115+
116+
class MacOsProductFactory : public IProductAbstractFactory {
117+
public:
118+
IGdbProduct* createGdbProduct() override { return new MacOsGdbProduct(); }
119+
ICMakeProduct* createCMakeProduct() override {
120+
return new MacOsCMakeProduct();
121+
}
122+
};
123+
124+
// ===================================================================================
125+
126+
/**
127+
* The client code works with factories and products only through abstract
128+
* types: AbstractFactory and AbstractProduct. This lets you pass any factory or
129+
* product subclass to the client code without breaking it.
130+
*/
131+
namespace ClientCode {
132+
void clientCode(IProductAbstractFactory* f) {
133+
ICMakeProduct* cmake = f->createCMakeProduct();
134+
IGdbProduct* gdb = f->createGdbProduct();
135+
cmake->launch();
136+
gdb->launch();
137+
138+
delete cmake;
139+
delete gdb;
140+
}
141+
} // namespace ClientCode
142+
143+
// static redudant inside anonymous namespace
144+
IProductAbstractFactory* createProductFactory(const std::string& os) {
145+
if (os == "linux") {
146+
return new LinuxProductFactory();
147+
} else if (os == "windows") {
148+
return new WindowsProductFactory();
149+
} else if (os == "macos") {
150+
return new MacOsProductFactory();
151+
} else {
152+
std::cout << "OS not support yet - " << os << "\n";
153+
return nullptr;
154+
}
155+
}
156+
157+
void run() {
158+
std::string os = "linux";
159+
IProductAbstractFactory* factory = createProductFactory(os);
160+
ClientCode::clientCode(factory);
161+
delete factory;
162+
}
163+
} // namespace AbstractFactory
164+
} // namespace
165+
166+
struct AbstractFactoryAutoRunner {
167+
AbstractFactoryAutoRunner() {
168+
std::cout << "\n--- AbstractFactory Pattern Example ---\n";
169+
AbstractFactory::run();
170+
}
171+
};
172+
173+
static AbstractFactoryAutoRunner instance;

src/patterns/creational/FactoryMethod.cpp

Lines changed: 25 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -51,22 +51,23 @@ class MacOsGdbProduct : public IGdbProduct {
5151
}
5252
};
5353

54+
// ===================================================================================
55+
5456
/**
5557
* The Creator class declares the factory method that is supposed to return an
5658
* object of a Product class. The Creator's subclasses usually provide the
57-
* implementation of this method.
59+
* implementation of this method. (a.k.a IGdbFactory)
5860
*/
59-
class IGdbCreator {
61+
class IGdbFactory {
6062
public:
61-
virtual ~IGdbCreator() = default;
63+
virtual ~IGdbFactory() = default;
6264
virtual IGdbProduct* factoryMethod() = 0;
6365
virtual void launchGdb() = 0;
6466
};
6567

66-
class AbstractGdbCreater : public IGdbCreator {
68+
class AbstractGdbFactory : public IGdbFactory {
6769
public:
68-
// Call the factory method to create a Product object.
69-
70+
// Call the factory method to create a Product object.
7071
void launchGdb() override final {
7172
IGdbProduct* gdb = this->factoryMethod();
7273
gdb->launch();
@@ -78,52 +79,51 @@ class AbstractGdbCreater : public IGdbCreator {
7879
* Concrete Creators override the factory method in order to change the
7980
* resulting product's type.
8081
*/
81-
class WindowsGdbCreator : public AbstractGdbCreater {
82+
class WindowsGdbFactory : public AbstractGdbFactory {
8283
public:
8384
IGdbProduct* factoryMethod() override { return new WindowsGdbProduct(); }
8485
};
8586

86-
class LinuxGdbCreator : public AbstractGdbCreater {
87+
class LinuxGdbFactory : public AbstractGdbFactory {
8788
public:
8889
IGdbProduct* factoryMethod() override { return new LinuxGdbProduct(); }
8990
};
9091

91-
class MacOsGdbCreator : public AbstractGdbCreater {
92+
class MacOsGdbFactory : public AbstractGdbFactory {
9293
public:
9394
IGdbProduct* factoryMethod() override { return new MacOsGdbProduct(); }
9495
};
9596

97+
// ===================================================================================
98+
9699
/**
97100
* The client code works with an instance of a concrete creator, albeit through
98101
* its base interface. As long as the client keeps working with the creator via
99102
* the base interface, you can pass it any creator's subclass.
100103
*/
101104
namespace ClientCode {
102-
void clientCode(IGdbCreator* gdb) {
105+
void clientCode(IGdbFactory* gdb) {
103106
if (gdb != nullptr)
104107
gdb->launchGdb();
105108
}
106109
} // namespace ClientCode
107110

108-
class GdbCreatorFactory {
109-
public:
110-
static IGdbCreator* createGdbCreator(const std::string& os) {
111-
if (os == "linux") {
112-
return new LinuxGdbCreator();
113-
} else if (os == "windows") {
114-
return new WindowsGdbCreator();
115-
} else if (os == "macos") {
116-
return new MacOsGdbCreator();
117-
} else {
118-
std::cout << "OS not support yet - " << os << "\n";
119-
return nullptr;
120-
}
111+
IGdbFactory* createGdbFactory(const std::string& os) {
112+
if (os == "linux") {
113+
return new LinuxGdbFactory();
114+
} else if (os == "windows") {
115+
return new WindowsGdbFactory();
116+
} else if (os == "macos") {
117+
return new MacOsGdbFactory();
118+
} else {
119+
std::cout << "OS not support yet - " << os << "\n";
120+
return nullptr;
121121
}
122-
};
122+
}
123123

124124
void run() {
125125
std::string os = "linux";
126-
IGdbCreator* gdb = GdbCreatorFactory::createGdbCreator(os);
126+
IGdbFactory* gdb = createGdbFactory(os);
127127
ClientCode::clientCode(gdb);
128128
delete gdb;
129129
}

0 commit comments

Comments
 (0)