Skip to content

Commit 35e7e74

Browse files
authored
Merge pull request #6 from urboob21/dev_branch
Add bridge pattern
2 parents 223ecef + 99291a3 commit 35e7e74

4 files changed

Lines changed: 214 additions & 1 deletion

File tree

‎.gitignore‎

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11
*build
22
*private*
3-
*.vscode
3+
*.vscode
4+
*Identifier

‎CMakeLists.txt‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,7 @@ set(APP_SOURCES
9090
"src/core/datatypes/class/CConstructors.cpp"
9191
"src/core/datatypes/class/CDestructors.cpp"
9292
"src/patterns/structural/Adapter.cpp"
93+
"src/patterns/structural/Bridge.cpp"
9394
)
9495

9596
# Test files

‎docs/uml/patterns_structural_bridge.drawio.svg‎

Lines changed: 4 additions & 0 deletions
Loading

‎src/patterns/structural/Bridge.cpp‎

Lines changed: 207 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,207 @@
1+
#include <iostream>
2+
3+
namespace Problem
4+
{
5+
class Widget
6+
{
7+
public:
8+
virtual ~Widget() = default;
9+
virtual std::string clickOn() const = 0;
10+
};
11+
12+
/* Concrete variations for Button */
13+
class Button : public Widget
14+
{
15+
public:
16+
virtual ~Button() = default;
17+
18+
public:
19+
std::string clickOn() const override
20+
{
21+
return "Click on: Button\n";
22+
}
23+
};
24+
25+
class ButtonWindows : public Button
26+
{
27+
public:
28+
std::string clickOn() const override
29+
{
30+
return "[Linux]" + Button::clickOn();
31+
}
32+
};
33+
34+
class ButtonLinux : public Button
35+
{
36+
public:
37+
std::string clickOn() const override
38+
{
39+
return "[Windows]" + Button::clickOn();
40+
}
41+
};
42+
43+
/* Concrete variations for Label */
44+
class Label : public Widget
45+
{
46+
public:
47+
virtual ~Label() = default;
48+
49+
public:
50+
std::string clickOn() const override
51+
{
52+
return "Click on: Label\n";
53+
}
54+
};
55+
56+
class LabelWindows : public Label
57+
{
58+
public:
59+
std::string clickOn() const override
60+
{
61+
return "[Windows]" + Label::clickOn();
62+
}
63+
};
64+
65+
class LabelLinux : public Label
66+
{
67+
public:
68+
std::string clickOn() const override
69+
{
70+
return "[Linux]" + Label::clickOn();
71+
}
72+
};
73+
74+
/* Concrete variations for others widgets like Text,CCombo or new platform macOS etc*/
75+
// [Problem 1] We have to write the Text/TextLinux ...
76+
77+
namespace Client
78+
{
79+
void clientCode(const Widget *widget)
80+
{
81+
if (widget != nullptr)
82+
std::cout << widget->clickOn();
83+
}
84+
}
85+
86+
void run()
87+
{
88+
// [Problem 2] : Use the Bridge if you need to be able to switch implementations at runtime. how to exmaple for this
89+
// still don't know
90+
Widget *button = new ButtonWindows();
91+
Client::clientCode(button);
92+
delete button;
93+
}
94+
}
95+
96+
namespace BridgePattern
97+
{
98+
/**
99+
* The Implementation defines the interface for all implementation classes. It
100+
* doesn't have to match the Abstraction's interface. In fact, the two
101+
* interfaces can be entirely different. Typically the Implementation interface
102+
* provides only primitive Widgets, while the Abstraction defines higher-
103+
* level Widgets based on those primitives.
104+
*/
105+
class OsImplemetation
106+
{
107+
public:
108+
virtual std::string clickOnImplement() const = 0;
109+
virtual ~OsImplemetation() = default;
110+
};
111+
112+
class WindowsImplemetation : public OsImplemetation
113+
{
114+
public:
115+
std::string clickOnImplement() const override
116+
{
117+
return "[Windows]";
118+
}
119+
};
120+
121+
class LinuxImplemetation : public OsImplemetation
122+
{
123+
public:
124+
std::string clickOnImplement() const override
125+
{
126+
return "[Linux]";
127+
}
128+
};
129+
130+
/**
131+
* The Abstraction defines the interface for the "control" part of the two class
132+
* hierarchies. It maintains a reference to an object of the Implementation
133+
* hierarchy and delegates all of the real work to this object.
134+
*/
135+
class WidgetAbstraction
136+
{
137+
protected:
138+
OsImplemetation *_implementation;
139+
140+
public:
141+
explicit WidgetAbstraction(OsImplemetation *implemetation) : _implementation{implemetation}
142+
{
143+
}
144+
virtual ~WidgetAbstraction() = default;
145+
146+
virtual std::string clickOn() const = 0;
147+
};
148+
149+
/**
150+
* We can extend the Abstraction without changing the Implementation classes.
151+
*/
152+
class ButtonAbstraction : public WidgetAbstraction
153+
{
154+
public:
155+
explicit ButtonAbstraction(OsImplemetation *implemetation) : WidgetAbstraction{implemetation} {}
156+
std::string clickOn() const override
157+
{
158+
return this->_implementation->clickOnImplement() + "Click on: Button\n";
159+
}
160+
};
161+
162+
class LabelAbstraction : public WidgetAbstraction
163+
{
164+
public:
165+
explicit LabelAbstraction(OsImplemetation *implemetation) : WidgetAbstraction{implemetation} {}
166+
std::string clickOn() const override
167+
{
168+
return this->_implementation->clickOnImplement() + "Click on: Label\n";
169+
}
170+
};
171+
172+
namespace Client
173+
{
174+
void clientCode(const WidgetAbstraction *widget)
175+
{
176+
if (widget != nullptr)
177+
std::cout << widget->clickOn();
178+
}
179+
}
180+
181+
void run()
182+
{
183+
// TODO: check memory leak here
184+
OsImplemetation *os = new WindowsImplemetation();
185+
WidgetAbstraction *widget = new ButtonAbstraction(os);
186+
Client::clientCode(widget);
187+
188+
os = new LinuxImplemetation();
189+
widget = new LabelAbstraction(os);
190+
Client::clientCode(widget);
191+
192+
delete os;
193+
delete widget;
194+
}
195+
}
196+
197+
struct BridgeAutoruner
198+
{
199+
BridgeAutoruner()
200+
{
201+
std::cout << "\n--- Bridge Pattern Example ---\n";
202+
Problem::run();
203+
BridgePattern::run();
204+
}
205+
};
206+
207+
static BridgeAutoruner instance;

0 commit comments

Comments
 (0)