Skip to content

Commit f08f5d8

Browse files
authored
Merge pull request #2 from ederfduran/master
C++ examples
2 parents 3431234 + e6681ce commit f08f5d8

File tree

49 files changed

+4603
-3
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

49 files changed

+4603
-3
lines changed

README.md

Lines changed: 37 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,16 +10,50 @@ It contains C++ examples for all classic GoF design patterns. Each pattern inclu
1010

1111
## Requirements
1212

13-
TODO
14-
13+
The examples were written as cross platform console application using c++11. It means that you should be able to compile and execute those examples with any recent compiler.
14+
15+
we recommend working with Visual Studio Code because it is a lightweight and cross-platform tool .It is a very complete IDE and is available for free (https://code.visualstudio.com/). You may need to install c++ extension and the compiler you prefer (The extension is still in preview and its focus is code editing, navigation, and debugging support for C and C++). For more information on how to use VSCode with c++ refer to: https://code.visualstudio.com/docs/languages/cpp .
16+
17+
For code execution in VSCode you will need to set up your task first. An example using g++ :
18+
19+
```sh
20+
{
21+
"version": "2.0.0",
22+
"tasks": [
23+
{
24+
"label": "build",
25+
"type": "shell",
26+
"command": "g++ -g -std=c++11 Conceptual/main.cc -o main",
27+
"group":{
28+
"kind": "build",
29+
"isDefault": true
30+
},
31+
"problemMatcher":"$gcc"
32+
}
33+
]
34+
}
35+
```
36+
Then you just need to start the executable.In case you have some doubts here you have an useful [tutorial] using vscode.
1537

1638
## Contributor's Guide
1739

18-
TODO
40+
I appreciate any help, whether it's a simple fix of a typo or a whole new example. Just make a fork, make your change and submit a pull request.
41+
42+
Here's a style guide which might help you to keep your changes consistent with the rest of the project's code:
43+
44+
1. All code should match the [Google style guide].
45+
2. Aim to put all code within one .cc file. Yes, I realize that it's not how it supposed to be done in production. However, it helps people to understand examples better, since all code fits into one screen.
46+
3. The comments doesn't follow the style guide for compatibility reasons withe other language examples.
47+
1948

2049

2150
## License
2251

2352
This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivatives 4.0 International License.
2453

2554
<a rel="license" href="http://creativecommons.org/licenses/by-nc-nd/4.0/"><img alt="Creative Commons License" style="border-width:0" src="https://i.creativecommons.org/l/by-nc-nd/4.0/80x15.png" /></a>
55+
56+
57+
58+
[Google style guide]: <https://google.github.io/styleguide/cppguide.html#C++_Version>
59+
[tutorial]: <https://www.youtube.com/watch?v=-erXR6k9TeE>
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
2+
Client: Testing client code with the first factory type:
3+
The result of the product B1.
4+
The result of the B1 collaborating with the (The result of the product A1.)
5+
6+
Client: Testing the same client code with the second factory type:
7+
The result of the product B2.
8+
The result of the B2 collaborating with the (The result of the product A2.)
Lines changed: 247 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,247 @@
1+
#include <iostream>
2+
#include <string>
3+
4+
/**
5+
* EN: Abstract Factory Design Pattern
6+
*
7+
* Intent: Lets you produce families of related objects without specifying their
8+
* concrete classes.
9+
*
10+
* RU: Паттерн Абстрактная Фабрика
11+
*
12+
* Назначение: Предоставляет интерфейс для создания семейств связанных или
13+
* зависимых объектов без привязки к их конкретным классам.
14+
*/
15+
/**
16+
* EN: The Abstract Factory interface declares a set of methods that return
17+
* different abstract products. These products are called a family and are
18+
* related by a high-level theme or concept. Products of one family are usually
19+
* able to collaborate among themselves. A family of products may have several
20+
* variants, but the products of one variant are incompatible with products of
21+
* another.
22+
*
23+
* RU: Интерфейс Абстрактной Фабрики объявляет набор методов, которые возвращают
24+
* различные абстрактные продукты. Эти продукты называются семейством и связаны
25+
* темой или концепцией высокого уровня. Продукты одного семейства обычно могут
26+
* взаимодействовать между собой. Семейство продуктов может иметь несколько
27+
* вариаций, но продукты одной вариации несовместимы с продуктами другой.
28+
*/
29+
30+
class AbstractProductA;
31+
class AbstractProductB;
32+
33+
class AbstractFactory
34+
{
35+
public:
36+
virtual AbstractProductA* CreateProductA() const = 0;
37+
virtual AbstractProductB* CreateProductB() const = 0;
38+
};
39+
40+
/**
41+
* EN: Each distinct product of a product family should have a base interface.
42+
* All variants of the product must implement this interface.
43+
*
44+
* RU: Каждый отдельный продукт семейства продуктов должен иметь базовый
45+
* интерфейс. Все вариации продукта должны реализовывать этот интерфейс.
46+
*/
47+
48+
class AbstractProductA
49+
{
50+
/**
51+
* EN: Define virtual destructor in case you need it.
52+
*
53+
* RU:
54+
*/
55+
public:
56+
virtual ~AbstractProductA(){};
57+
virtual std::string UsefulFunctionA() const = 0;
58+
};
59+
60+
61+
/**
62+
* EN: Concrete Products are created by corresponding Concrete Factories.
63+
*
64+
* RU: Конкретные продукты создаются соответствующими Конкретными Фабриками.
65+
*/
66+
67+
class ConcreteProductA1 : public AbstractProductA
68+
{
69+
public:
70+
std::string UsefulFunctionA() const override
71+
{
72+
return "The result of the product A1.";
73+
}
74+
};
75+
76+
class ConcreteProductA2 : public AbstractProductA
77+
{
78+
std::string UsefulFunctionA() const override
79+
{
80+
return "The result of the product A2.";
81+
}
82+
};
83+
84+
/**
85+
* EN: Here's the the base interface of another product. All products can
86+
* interact with each other, but proper interaction is possible only between
87+
* products of the same concrete variant.
88+
*
89+
* RU: Базовый интерфейс другого продукта. Все продукты могут взаимодействовать
90+
* друг с другом, но правильное взаимодействие возможно только между продуктами
91+
* одной и той же конкретной вариации.
92+
*/
93+
94+
class AbstractProductB
95+
{
96+
/**
97+
* EN: Product B is able to do its own thing...
98+
*
99+
* RU: Продукт B способен работать самостоятельно...
100+
*/
101+
public:
102+
virtual ~AbstractProductB(){};
103+
104+
virtual std::string UsefulFunctionB() const = 0;
105+
/**
106+
* EN: ...but it also can collaborate with the ProductA.
107+
*
108+
* The Abstract Factory makes sure that all products it creates are of the
109+
* same variant and thus, compatible.
110+
*
111+
* RU: ...а также взаимодействовать с Продуктами Б той же вариации.
112+
*
113+
* Абстрактная Фабрика гарантирует, что все продукты, которые она создает,
114+
* имеют одинаковую вариацию и, следовательно, совместимы.
115+
*/
116+
virtual std::string AnotherUsefulFunctionB(const AbstractProductA& collaborator) const = 0;
117+
};
118+
119+
/**
120+
* EN: Concrete Products are created by corresponding Concrete Factories.
121+
*
122+
* RU: Конкретные Продукты создаются соответствующими Конкретными Фабриками.
123+
*/
124+
125+
class ConcreteProductB1: public AbstractProductB{
126+
public:
127+
128+
std::string UsefulFunctionB() const override{
129+
return "The result of the product B1.";
130+
}
131+
/**
132+
* EN: The variant, Product B1, is only able to work correctly with the
133+
* variant, Product A1. Nevertheless, it accepts any instance of
134+
* AbstractProductA as an argument.
135+
*
136+
* RU: Продукт B1 может корректно работать только с Продуктом A1. Тем не
137+
* менее, он принимает любой экземпляр Абстрактного Продукта А в качестве
138+
* аргумента.
139+
*/
140+
std::string AnotherUsefulFunctionB(const AbstractProductA& collaborator) const override{
141+
const std::string result= collaborator.UsefulFunctionA();
142+
return "The result of the B1 collaborating with ( "+ result+" )";
143+
}
144+
};
145+
146+
class ConcreteProductB2: public AbstractProductB{
147+
public:
148+
std::string UsefulFunctionB() const override{
149+
return "The result of the product B2.";
150+
}
151+
152+
/**
153+
* EN: The variant, Product B2, is only able to work correctly with the
154+
* variant, Product A2. Nevertheless, it accepts any instance of
155+
* AbstractProductA as an argument.
156+
*
157+
* RU: Продукт B2 может корректно работать только с Продуктом A2. Тем не
158+
* менее, он принимает любой экземпляр Абстрактного Продукта А в качестве
159+
* аргумента.
160+
*/
161+
std::string AnotherUsefulFunctionB(const AbstractProductA& collaborator) const override{
162+
const std::string result= collaborator.UsefulFunctionA();
163+
return "The result of the B2 collaborating with ( "+ result+" )";
164+
}
165+
};
166+
167+
168+
169+
/**
170+
* EN: Concrete Factories produce a family of products that belong to a single
171+
* variant. The factory guarantees that resulting products are compatible. Note
172+
* that signatures of the Concrete Factory's methods return an abstract product,
173+
* while inside the method a concrete product is instantiated.
174+
*
175+
* RU: Конкретная Фабрика производит семейство продуктов одной вариации. Фабрика
176+
* гарантирует совместимость полученных продуктов. Обратите внимание, что
177+
* сигнатуры методов Конкретной Фабрики возвращают абстрактный продукт, в то
178+
* время как внутри метода создается экземпляр конкретного продукта.
179+
*/
180+
181+
class ConcreteFactory1 : public AbstractFactory
182+
{
183+
public:
184+
AbstractProductA* CreateProductA() const override
185+
{
186+
return new ConcreteProductA1();
187+
}
188+
189+
AbstractProductB* CreateProductB() const override
190+
{
191+
return new ConcreteProductB1();
192+
}
193+
};
194+
/**
195+
* EN: Each Concrete Factory has a corresponding product variant.
196+
*
197+
* RU: Каждая Конкретная Фабрика имеет соответствующую вариацию продукта.
198+
*/
199+
200+
class ConcreteFactory2 : public AbstractFactory
201+
{
202+
public:
203+
AbstractProductA* CreateProductA() const override
204+
{
205+
return new ConcreteProductA2();
206+
}
207+
208+
AbstractProductB* CreateProductB() const override
209+
{
210+
return new ConcreteProductB2();
211+
}
212+
};
213+
214+
215+
216+
217+
/**
218+
* EN: The client code works with factories and products only through abstract
219+
* types: AbstractFactory and AbstractProduct. This lets you pass any factory or
220+
* product subclass to the client code without breaking it.
221+
*
222+
* RU: Клиентский код работает с фабриками и продуктами только через абстрактные
223+
* типы: Абстрактная Фабрика и Абстрактный Продукт. Это позволяет передавать
224+
* любой подкласс фабрики или продукта клиентскому коду, не нарушая его.
225+
*/
226+
227+
void ClientCode(const AbstractFactory& factory){
228+
const AbstractProductA* product_a =factory.CreateProductA();
229+
const AbstractProductB* product_b =factory.CreateProductB();
230+
std::cout << product_b->UsefulFunctionB() << "\n";
231+
std::cout << product_b->AnotherUsefulFunctionB(*product_a) << "\n";
232+
delete product_a;
233+
delete product_b;
234+
}
235+
236+
int main(){
237+
std::cout << "Client: Testing client code with the first factory type:\n";
238+
ConcreteFactory1* f1= new ConcreteFactory1();
239+
ClientCode(*f1);
240+
delete f1;
241+
std::cout << std::endl;
242+
std::cout << "Client: Testing the same client code with the second factory type:\n";
243+
ConcreteFactory2* f2= new ConcreteFactory2();
244+
ClientCode(*f2);
245+
delete f2;
246+
return 0;
247+
}
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
Client: I can work just fine with the Target objects:
2+
Target: The default target's behavior.
3+
4+
Client: The Adaptee class has a weird interface. See, I don't understand it:
5+
Adaptee: .eetpadA eht fo roivaheb laicepS
6+
7+
Client: But I can work with it via the Adapter:
8+
Adapter: (TRANSLATED) Special behavior of the Adaptee.
9+
10+

0 commit comments

Comments
 (0)