|
1 |
| -using System; |
| 1 | +// EN: Visitor Design Pattern |
| 2 | +// |
| 3 | +// Intent: Represent an operation to be performed over elements of an object |
| 4 | +// structure. The Visitor pattern lets you define a new operation without |
| 5 | +// changing the classes of the elements on which it operates. |
| 6 | +// |
| 7 | +// RU: Паттерн Посетитель |
| 8 | +// |
| 9 | +// Назначение: Позволяет добавлять в программу новые операции, не изменяя классы |
| 10 | +// объектов, над которыми эти операции могут выполняться. |
| 11 | + |
| 12 | +using System; |
2 | 13 | using System.Collections.Generic;
|
3 | 14 |
|
4 | 15 | namespace RefactoringGuru.DesignPatterns.Visitor.Conceptual
|
5 | 16 | {
|
6 |
| - interface Component |
| 17 | + // EN: The Component interface declares an `accept` method that should take the |
| 18 | + // base visitor interface as an argument. |
| 19 | + // |
| 20 | + // RU: Интерфейс Компонента объявляет метод accept, который в качестве |
| 21 | + // аргумента может получать любой объект, реализующий интерфейс посетителя. |
| 22 | + public interface Component |
7 | 23 | {
|
8 |
| - void accept(Visitor visitor); |
| 24 | + void Accept(Visitor visitor); |
9 | 25 | }
|
10 | 26 |
|
| 27 | + // EN: Each Concrete Component must implement the `Accept` method in such a way |
| 28 | + // that it calls the visitor's method corresponding to the component's class. |
| 29 | + // |
| 30 | + // RU: Каждый Конкретный Компонент должен реализовать метод Accept таким |
| 31 | + // образом, чтобы он вызывал метод посетителя, соответствующий классу компонента. |
11 | 32 | public class ConcreteComponentA : Component
|
12 | 33 | {
|
13 |
| - public void accept(Visitor visitor) |
| 34 | + // EN: Note that we're calling `VisitConcreteComponentA`, which matches the |
| 35 | + // current class name. This way we let the visitor know the class of the |
| 36 | + // component it works with. |
| 37 | + // |
| 38 | + // RU: Обратите внимание, мы вызываем VisitConcreteComponentA, что |
| 39 | + // соответствует названию текущего класса. Таким образом мы позволяем |
| 40 | + // посетителю узнать, с каким классом компонента он работает. |
| 41 | + public void Accept(Visitor visitor) |
14 | 42 | {
|
15 |
| - visitor.visitConcreteComponentA(this); |
| 43 | + visitor.VisitConcreteComponentA(this); |
16 | 44 | }
|
17 | 45 |
|
18 |
| - public string exclusiveMethodOfConcreteComponentA() |
| 46 | + // EN: Concrete Components may have special methods that don't exist in |
| 47 | + // their base class or interface. The Visitor is still able to use these |
| 48 | + // methods since it's aware of the component's concrete class. |
| 49 | + // |
| 50 | + // RU: Конкретные Компоненты могут иметь особые методы, не объявленные в их |
| 51 | + // базовом классе или интерфейсе. Посетитель всё же может использовать эти |
| 52 | + // методы, поскольку он знает о конкретном классе компонента. |
| 53 | + public string ExclusiveMethodOfConcreteComponentA() |
19 | 54 | {
|
20 | 55 | return "A";
|
21 | 56 | }
|
22 | 57 | }
|
23 | 58 |
|
24 | 59 | public class ConcreteComponentB : Component
|
25 | 60 | {
|
26 |
| - public void accept(Visitor visitor) |
| 61 | + // EN: Same here: VisitConcreteComponentB => ConcreteComponentB |
| 62 | + // |
| 63 | + // RU: То же самое здесь: VisitConcreteComponentB => ConcreteComponentB |
| 64 | + public void Accept(Visitor visitor) |
27 | 65 | {
|
28 |
| - visitor.visitConcreteComponentB(this); |
| 66 | + visitor.VisitConcreteComponentB(this); |
29 | 67 | }
|
30 | 68 |
|
31 |
| - public string specialMethodOfConcreteComponentB() |
| 69 | + public string SpecialMethodOfConcreteComponentB() |
32 | 70 | {
|
33 | 71 | return "B";
|
34 | 72 | }
|
35 | 73 | }
|
36 | 74 |
|
| 75 | + // EN: The Visitor Interface declares a set of visiting methods that correspond |
| 76 | + // to component classes. The signature of a visiting method allows the visitor |
| 77 | + // to identify the exact class of the component that it's dealing with. |
| 78 | + // |
| 79 | + // RU: Интерфейс Посетителя объявляет набор методов посещения, соответствующих |
| 80 | + // классам компонентов. Сигнатура метода посещения позволяет посетителю |
| 81 | + // определить конкретный класс компонента, с которым он имеет дело. |
37 | 82 | public interface Visitor
|
38 | 83 | {
|
39 |
| - void visitConcreteComponentA(ConcreteComponentA el); |
| 84 | + void VisitConcreteComponentA(ConcreteComponentA element); |
40 | 85 |
|
41 |
| - void visitConcreteComponentB(ConcreteComponentB el); |
| 86 | + void VisitConcreteComponentB(ConcreteComponentB element); |
42 | 87 | }
|
43 | 88 |
|
| 89 | + // EN: Concrete Visitors implement several versions of the same algorithm, which |
| 90 | + // can work with all concrete component classes. |
| 91 | + // |
| 92 | + // You can experience the biggest benefit of the Visitor pattern when using it |
| 93 | + // with a complex object structure, such as a Composite tree. In this case, it |
| 94 | + // might be helpful to store some intermediate state of the algorithm while |
| 95 | + // executing visitor's methods over various objects of the structure. |
| 96 | + // |
| 97 | + // RU: Конкретные Посетители реализуют несколько версий одного и того же |
| 98 | + // алгоритма, которые могут работать со всеми классами конкретных компонентов. |
| 99 | + // |
| 100 | + // Максимальную выгоду от паттерна Посетитель вы почувствуете, используя его со |
| 101 | + // сложной структурой объектов, такой как дерево Компоновщика. В этом случае |
| 102 | + // было бы полезно хранить некоторое промежуточное состояние алгоритма при |
| 103 | + // выполнении методов посетителя над различными объектами структуры. |
44 | 104 | class ConcreteVisitor1 : Visitor
|
45 | 105 | {
|
46 |
| - public void visitConcreteComponentA(ConcreteComponentA el) |
| 106 | + public void VisitConcreteComponentA(ConcreteComponentA element) |
47 | 107 | {
|
48 |
| - Console.Write(el.exclusiveMethodOfConcreteComponentA() + " + ConcreteVisitor1\n"); |
| 108 | + Console.WriteLine(element.ExclusiveMethodOfConcreteComponentA() + " + ConcreteVisitor1"); |
49 | 109 | }
|
50 | 110 |
|
51 |
| - public void visitConcreteComponentB(ConcreteComponentB el) |
| 111 | + public void VisitConcreteComponentB(ConcreteComponentB element) |
52 | 112 | {
|
53 |
| - Console.Write(el.specialMethodOfConcreteComponentB() + " + ConcreteVisitor1\n"); |
| 113 | + Console.WriteLine(element.SpecialMethodOfConcreteComponentB() + " + ConcreteVisitor1"); |
54 | 114 | }
|
55 | 115 | }
|
56 | 116 |
|
57 | 117 | class ConcreteVisitor2 : Visitor
|
58 | 118 | {
|
59 |
| - public void visitConcreteComponentA(ConcreteComponentA el) |
| 119 | + public void VisitConcreteComponentA(ConcreteComponentA element) |
60 | 120 | {
|
61 |
| - Console.Write(el.exclusiveMethodOfConcreteComponentA() + " + ConcreteVisitor2\n"); |
| 121 | + Console.WriteLine(element.ExclusiveMethodOfConcreteComponentA() + " + ConcreteVisitor2"); |
62 | 122 | }
|
63 | 123 |
|
64 |
| - public void visitConcreteComponentB(ConcreteComponentB el) |
| 124 | + public void VisitConcreteComponentB(ConcreteComponentB element) |
65 | 125 | {
|
66 |
| - Console.Write(el.specialMethodOfConcreteComponentB() + " + ConcreteVisitor2\n"); |
| 126 | + Console.WriteLine(element.SpecialMethodOfConcreteComponentB() + " + ConcreteVisitor2"); |
67 | 127 | }
|
68 | 128 | }
|
69 | 129 |
|
70 |
| - internal class Client |
| 130 | + public class Client |
71 | 131 | {
|
72 |
| - internal static void ClientCode(List<Component> components, Visitor visitor) |
| 132 | + // EN: The client code can run visitor operations over any set of elements |
| 133 | + // without figuring out their concrete classes. The accept operation directs a |
| 134 | + // call to the appropriate operation in the visitor object. |
| 135 | + // |
| 136 | + // RU: Клиентский код может выполнять операции посетителя над любым набором |
| 137 | + // элементов, не выясняя их конкретных классов. Операция принятия направляет |
| 138 | + // вызов к соответствующей операции в объекте посетителя. |
| 139 | + public static void ClientCode(List<Component> components, Visitor visitor) |
73 | 140 | {
|
74 | 141 | foreach (var component in components)
|
75 | 142 | {
|
76 |
| - component.accept(visitor); |
| 143 | + component.Accept(visitor); |
77 | 144 | }
|
78 | 145 | }
|
79 | 146 | }
|
|
0 commit comments