Skip to content

Commit f27076b

Browse files
committed
Decorator: improve conceptual example
1 parent 5732903 commit f27076b

File tree

2 files changed

+109
-38
lines changed

2 files changed

+109
-38
lines changed

Decorator.Conceptual/Output.txt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
Client: I get a sumple component:
1+
Client: I get a simple component:
22
RESULT: ConcreteComponent
33

4-
Client: Now I get a decorated component:
4+
Client: Now I've got a decorated component:
55
RESULT: ConcreteDecoratorB(ConcreteDecoratorA(ConcreteComponent))

Decorator.Conceptual/Program.cs

Lines changed: 107 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -1,38 +1,34 @@
1-
using System;
1+
// EN: Decorator Design Pattern
2+
//
3+
// Intent: Attach additional responsibilities to an object dynamically.
4+
// Decorators provide a flexible alternative to subclassing for extending
5+
// functionality.
6+
//
7+
// RU: Паттерн Декоратор
8+
//
9+
// Назначение: Динамически подключает к объекту дополнительную функциональность.
10+
// Декораторы предоставляют гибкую альтернативу практике создания подклассов для
11+
// расширения функциональности.
12+
13+
using System;
214

315
namespace RefactoringGuru.DesignPatterns.Composite.Conceptual
416
{
5-
class Program
6-
{
7-
static void Main(string[] args)
8-
{
9-
Client client = new Client();
10-
11-
var simple = new ConcreteComponent();
12-
Console.WriteLine("Client: I get a sumple component:");
13-
client.ClientCode(simple);
14-
Console.WriteLine();
15-
16-
ConcreteDecoratorA d1 = new ConcreteDecoratorA(simple);
17-
ConcreteDecoratorB d2 = new ConcreteDecoratorB(d1);
18-
Console.WriteLine("Client: Now I get a decorated component:");
19-
client.ClientCode(d2);
20-
}
21-
}
22-
23-
public class Client
24-
{
25-
public void ClientCode(Component component)
26-
{
27-
Console.WriteLine("RESULT: " + component.Operation());
28-
}
29-
}
30-
17+
// EN: The base Component interface defines operations that can be altered
18+
// by decorators.
19+
//
20+
// RU: Базовый интерфейс Компонента определяет поведение, которое изменяется
21+
// декораторами.
3122
public abstract class Component
3223
{
3324
public abstract string Operation();
3425
}
3526

27+
// EN: Concrete Components provide default implementations of the
28+
// operations. There might be several variations of these classes.
29+
//
30+
// RU: Конкретные Компоненты предоставляют реализации поведения по
31+
// умолчанию. Может быть несколько вариаций этих классов.
3632
class ConcreteComponent : Component
3733
{
3834
public override string Operation()
@@ -41,25 +37,41 @@ public override string Operation()
4137
}
4238
}
4339

40+
// EN: The base Decorator class follows the same interface as the other
41+
// components. The primary purpose of this class is to define the wrapping
42+
// interface for all concrete decorators. The default implementation of the
43+
// wrapping code might include a field for storing a wrapped component and
44+
// the means to initialize it.
45+
//
46+
// RU: Базовый класс Декоратора следует тому же интерфейсу, что и другие
47+
// компоненты. Основная цель этого класса - определить интерфейс обёртки для
48+
// всех конкретных декораторов. Реализация кода обёртки по умолчанию может
49+
// включать в себя поле для хранения завёрнутого компонента и средства его
50+
// инициализации.
4451
abstract class Decorator : Component
4552
{
46-
protected Component component;
53+
protected Component _component;
4754

48-
public void SetComponent(Component component)
55+
public Decorator(Component component)
4956
{
50-
this.component = component;
57+
this._component = component;
5158
}
5259

53-
public Decorator(Component component)
60+
public void SetComponent(Component component)
5461
{
55-
this.component = component;
62+
this._component = component;
5663
}
5764

65+
//
66+
// EN: The Decorator delegates all work to the wrapped component.
67+
//
68+
// RU: Декоратор делегирует всю работу обёрнутому компоненту.
69+
///
5870
public override string Operation()
5971
{
60-
if (component != null)
72+
if (this._component != null)
6173
{
62-
return component.Operation();
74+
return this._component.Operation();
6375
}
6476
else
6577
{
@@ -68,18 +80,35 @@ public override string Operation()
6880
}
6981
}
7082

83+
// EN: Concrete Decorators call the wrapped object and alter its result in some
84+
// way.
85+
//
86+
// RU: Конкретные Декораторы вызывают обёрнутый объект и изменяют его результат
87+
// некоторым образом.
7188
class ConcreteDecoratorA : Decorator
7289
{
7390
public ConcreteDecoratorA(Component comp) : base(comp)
7491
{
7592
}
7693

94+
// EN: Decorators may call parent implementation of the operation, instead
95+
// of calling the wrapped object directly. This approach simplifies
96+
// extension of decorator classes.
97+
//
98+
// RU: Декораторы могут вызывать родительскую реализацию операции, вместо
99+
// того, чтобы вызвать обёрнутый объект напрямую. Такой подход упрощает
100+
// расширение классов декораторов.
77101
public override string Operation()
78102
{
79-
return "ConcreteDecoratorA(" + base.Operation() + ")";
103+
return $"ConcreteDecoratorA({base.Operation()})";
80104
}
81105
}
82106

107+
// EN: Decorators can execute their behavior either before or after the call to
108+
// a wrapped object.
109+
//
110+
// RU: Декораторы могут выполнять своё поведение до или после вызова обёрнутого
111+
// объекта.
83112
class ConcreteDecoratorB : Decorator
84113
{
85114
public ConcreteDecoratorB(Component comp) : base(comp)
@@ -88,7 +117,49 @@ public ConcreteDecoratorB(Component comp) : base(comp)
88117

89118
public override string Operation()
90119
{
91-
return "ConcreteDecoratorB(" + base.Operation() + ")";
120+
return $"ConcreteDecoratorB({base.Operation()})";
121+
}
122+
}
123+
124+
public class Client
125+
{
126+
// EN: The client code works with all objects using the Component interface.
127+
// This way it can stay independent of the concrete classes of components it
128+
// works with.
129+
//
130+
// RU: Клиентский код работает со всеми объектами, используя интерфейс
131+
// Компонента. Таким образом, он остаётся независимым от конкретных классов
132+
// компонентов, с которыми работает.
133+
public void ClientCode(Component component)
134+
{
135+
Console.WriteLine("RESULT: " + component.Operation());
136+
}
137+
}
138+
139+
class Program
140+
{
141+
static void Main(string[] args)
142+
{
143+
Client client = new Client();
144+
145+
var simple = new ConcreteComponent();
146+
Console.WriteLine("Client: I get a simple component:");
147+
client.ClientCode(simple);
148+
Console.WriteLine();
149+
150+
// EN: ...as well as decorated ones.
151+
//
152+
// Note how decorators can wrap not only simple components but the other
153+
// decorators as well.
154+
//
155+
// RU: ...так и декорированные.
156+
//
157+
// Обратите внимание, что декораторы могут обёртывать не только простые
158+
// компоненты, но и другие декораторы.
159+
ConcreteDecoratorA decorator1 = new ConcreteDecoratorA(simple);
160+
ConcreteDecoratorB decorator2 = new ConcreteDecoratorB(decorator1);
161+
Console.WriteLine("Client: Now I've got a decorated component:");
162+
client.ClientCode(decorator2);
92163
}
93164
}
94165
}

0 commit comments

Comments
 (0)