1
- using System ;
1
+ // EN: Chain of Responsibility Design Pattern
2
+ //
3
+ // Intent: Avoid coupling a sender of a request to its receiver by giving more
4
+ // than one object a chance to handle the request. Chain the receiving objects
5
+ // and then pass the request through the chain until some receiver handles it.
6
+ //
7
+ // RU: Паттерн Цепочка обязанностей
8
+ //
9
+ // Назначение: Позволяет избежать привязки отправителя запроса к его получателю,
10
+ // предоставляя возможность обработать запрос нескольким объектам. Связывает в
11
+ // цепочку объекты-получатели, а затем передаёт запрос по цепочке, пока некий
12
+ // получатель не обработает его.
13
+
14
+ using System ;
2
15
using System . Collections . Generic ;
3
16
4
17
namespace RefactoringGuru . DesignPatterns . ChainOfResponsibility . Conceptual
5
18
{
19
+ // EN: The Handler interface declares a method for building the chain of
20
+ // handlers. It also declares a method for executing a request.
21
+ //
22
+ // RU: Интерфейс Обработчика объявляет метод построения цепочки
23
+ // обработчиков. Он также объявляет метод для выполнения запроса.
6
24
interface Handler
7
25
{
8
- Handler setNext ( Handler handler ) ;
26
+ Handler SetNext ( Handler handler ) ;
9
27
10
28
object Handle ( object request ) ;
11
29
}
12
30
31
+ // EN: The default chaining behavior can be implemented inside a base handler
32
+ // class.
33
+ //
34
+ // RU: Поведение цепочки по умолчанию может быть реализовано внутри базового
35
+ // класса обработчика.
13
36
abstract class AbstractHandler : Handler
14
37
{
15
- private Handler nextHandler ;
38
+ private Handler _nextHandler ;
16
39
17
- public Handler setNext ( Handler handler )
40
+ public Handler SetNext ( Handler handler )
18
41
{
19
- this . nextHandler = handler ;
42
+ this . _nextHandler = handler ;
43
+
44
+ // EN: Returning a handler from here will let us link handlers in a
45
+ // convenient way like this:
46
+ // monkey.SetNext(squirrel).SetNext(dog);
47
+ //
48
+ // RU: Возврат обработчика отсюда позволит связать обработчики
49
+ // простым способом, вот так:
50
+ // monkey.SetNext(squirrel).SetNext(dog);
20
51
return handler ;
21
52
}
22
53
23
54
public virtual object Handle ( object request )
24
55
{
25
- if ( this . nextHandler != null )
56
+ if ( this . _nextHandler != null )
26
57
{
27
- return this . nextHandler . Handle ( request ) ;
58
+ return this . _nextHandler . Handle ( request ) ;
28
59
}
29
60
else
30
61
{
@@ -39,7 +70,7 @@ public override object Handle(object request)
39
70
{
40
71
if ( ( request as string ) == "Banana" )
41
72
{
42
- return "Monkey: I'll eat the " + request . ToString ( ) + " .\n ";
73
+ return $ "Monkey: I'll eat the { request . ToString ( ) } .\n ";
43
74
}
44
75
else
45
76
{
@@ -54,7 +85,7 @@ public override object Handle(object request)
54
85
{
55
86
if ( request . ToString ( ) == "Nut" )
56
87
{
57
- return "Squirrel: I'll eat the " + request . ToString ( ) + " .\n ";
88
+ return $ "Squirrel: I'll eat the { request . ToString ( ) } .\n ";
58
89
}
59
90
else
60
91
{
@@ -69,7 +100,7 @@ public override object Handle(object request)
69
100
{
70
101
if ( request . ToString ( ) == "MeatBall" )
71
102
{
72
- return "Dog: I'll eat the " + request . ToString ( ) + " .\n ";
103
+ return $ "Dog: I'll eat the { request . ToString ( ) } .\n ";
73
104
}
74
105
else
75
106
{
@@ -80,21 +111,27 @@ public override object Handle(object request)
80
111
81
112
class Client
82
113
{
114
+ // EN: The client code is usually suited to work with a single handler. In most
115
+ // cases, it is not even aware that the handler is part of a chain.
116
+ //
117
+ // RU: Обычно клиентский код приспособлен для работы с единственным
118
+ // обработчиком. В большинстве случаев клиенту даже неизвестно, что этот
119
+ // обработчик является частью цепочки.
83
120
public static void ClientCode ( AbstractHandler handler )
84
121
{
85
122
foreach ( var food in new List < string > { "Nut" , "Banana" , "Cup of coffee" } )
86
123
{
87
- Console . WriteLine ( "Client: Who wants a " + food + " ?") ;
124
+ Console . WriteLine ( $ "Client: Who wants a { food } ?") ;
88
125
89
126
var result = handler . Handle ( food ) ;
90
127
91
128
if ( result != null )
92
129
{
93
- Console . Write ( " " + result ) ;
130
+ Console . Write ( $ " { result } " ) ;
94
131
}
95
132
else
96
133
{
97
- Console . WriteLine ( " " + food + " was left untouched.") ;
134
+ Console . WriteLine ( $ " { food } was left untouched.") ;
98
135
}
99
136
}
100
137
}
@@ -104,13 +141,21 @@ class Program
104
141
{
105
142
static void Main ( string [ ] args )
106
143
{
144
+ // EN: The other part of the client code constructs the actual chain.
145
+ //
146
+ // RU: Другая часть клиентского кода создает саму цепочку.
107
147
var monkey = new MonkeyHandler ( ) ;
108
148
var squirrel = new SquirrelHandler ( ) ;
109
149
var dog = new DogHandler ( ) ;
110
150
111
- monkey . setNext ( squirrel ) . setNext ( dog ) ;
151
+ monkey . SetNext ( squirrel ) . SetNext ( dog ) ;
112
152
113
- Console . WriteLine ( "Chain: Monkey > Squirerel > Dog\n " ) ;
153
+ // EN: The client should be able to send a request to any handler, not just the
154
+ // first one in the chain.
155
+ //
156
+ // RU: Клиент должен иметь возможность отправлять запрос любому обработчику, а
157
+ // не только первому в цепочке.
158
+ Console . WriteLine ( "Chain: Monkey > Squirrel > Dog\n " ) ;
114
159
Client . ClientCode ( monkey ) ;
115
160
Console . WriteLine ( ) ;
116
161
0 commit comments