Repository navigation
Expand file tree
/
Copy pathDecorator.cpp
More file actions
134 lines (126 loc) · 3.65 KB
/
Copy pathDecorator.cpp
File metadata and controls
134 lines (126 loc) · 3.65 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
#include <iostream>
#include <memory>
/**
* The base Component interface defines operations that can be altered by
* decorators.
*/
class Component {
public:
Component()
{
std::cout << "Construct Component" << std::endl;
}
virtual ~Component()
{
std::cout << "Destruct Component" << std::endl;
}
virtual std::string Operation() const = 0;
};
/**
* Concrete Components provide default implementations of the operations. There
* might be several variations of these classes.
*/
class ConcreteComponent : public Component {
public:
ConcreteComponent()
{
std::cout << "Construct ConcreteComponent" << std::endl;
}
~ConcreteComponent()
{
std::cout << "Destruct ConcreteComponent" << std::endl;
}
std::string Operation() const override {
return "ConcreteComponent";
}
};
/**
* The base Decorator class follows the same interface as the other components.
* The primary purpose of this class is to define the wrapping interface for all
* concrete decorators. The default implementation of the wrapping code might
* include a field for storing a wrapped component and the means to initialize
* it.
*/
class Decorator : public Component {
/**
* @var Component
*/
protected:
Component* component_;
public:
Decorator(Component* component) : component_(component) {
std::cout << "Construct Decorator" << std::endl;
}
/**
* The Decorator delegates all work to the wrapped component.
*/
std::string Operation() const override {
return this->component_->Operation();
}
};
/**
* Concrete Decorators call the wrapped object and alter its result in some way.
*/
class ConcreteDecoratorA : public Decorator {
/**
* Decorators may call parent implementation of the operation, instead of
* calling the wrapped object directly. This approach simplifies extension of
* decorator classes.
*/
public:
ConcreteDecoratorA(Component* component) : Decorator(component) {
}
std::string Operation() const override {
return "ConcreteDecoratorA(" + Decorator::Operation() + ")";
}
};
/**
* Decorators can execute their behavior either before or after the call to a
* wrapped object.
*/
class ConcreteDecoratorB : public Decorator {
public:
ConcreteDecoratorB(Component* component) : Decorator(component) {
}
std::string Operation() const override {
return "ConcreteDecoratorB(" + Decorator::Operation() + ")";
}
};
/**
* The client code works with all objects using the Component interface. This
* way it can stay independent of the concrete classes of components it works
* with.
*/
void ClientCode(Component* component) {
// ...
std::cout << "RESULT: " << component->Operation();
// ...
}
int main() {
/**
* This way the client code can support both simple components...
*/
//Component* simple = new ConcreteComponent;
std::unique_ptr<Component> simple = std::make_unique<ConcreteComponent>();
std::cout << "Client: I've got a simple component:\n";
ClientCode(simple.get());
std::cout << "\n\n";
/**
* ...as well as decorated ones.
*
* Note how decorators can wrap not only simple components but the other
* decorators as well.
*/
//Component* decorator1 = new ConcreteDecoratorA(simple.get());
std::unique_ptr<Component> decorator1 = std::make_unique<ConcreteDecoratorA>(simple.get());
//Component* decorator2 = new ConcreteDecoratorB(decorator1.get());
ClientCode(decorator1.get());
std::unique_ptr<Component> decorator2 = std::make_unique<ConcreteDecoratorB>(decorator1.get());
std::cout << "Client: Now I've got a decorated component:\n";
ClientCode(decorator2.get());
std::cout << "\n";
//delete simple;
//delete decorator1;
//delete decorator2;
return 0;
}