Skip to content

Commit 64cb7b9

Browse files
committed
Template method: improve conceptual example
1 parent e439cad commit 64cb7b9

File tree

1 file changed

+101
-37
lines changed

1 file changed

+101
-37
lines changed

TemplateMethod.Conceptual/Program.cs

Lines changed: 101 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -1,93 +1,157 @@
1-
using System;
1+
// EN: Template Method Design Pattern
2+
//
3+
// Intent: Define the skeleton of an algorithm, deferring implementation of some
4+
// steps to subclasses. Template Method lets subclasses redefine specific steps
5+
// of an algorithm without changing the algorithm's structure.
6+
//
7+
// RU: Паттерн Шаблонный метод
8+
//
9+
// Назначение: Определяет общую схему алгоритма, перекладывая реализацию
10+
// некоторых шагов на подклассы. Шаблонный метод позволяет подклассам
11+
// переопределять отдельные шаги алгоритма без изменения структуры алгоритма.
12+
13+
using System;
214

315
namespace RefactoringGuru.DesignPatterns.TemplateMethod.Conceptual
416
{
17+
// EN: The Abstract Class defines a template method that contains a skeleton of
18+
// some algorithm, composed of calls to (usually) abstract primitive operations.
19+
//
20+
// Concrete subclasses should implement these operations, but leave the template
21+
// method itself intact.
22+
//
23+
// RU: Абстрактный Класс определяет шаблонный метод, содержащий скелет
24+
// некоторого алгоритма, состоящего из вызовов (обычно) абстрактных примитивных
25+
// операций.
26+
//
27+
// Конкретные подклассы должны реализовать эти операции, но оставить сам
28+
// шаблонный метод без изменений.
529
abstract class AbstractClass
630
{
7-
public void templateMethod()
31+
// EN: The template method defines the skeleton of an algorithm.
32+
//
33+
// RU: Шаблонный метод определяет скелет алгоритма.
34+
public void TemplateMethod()
835
{
9-
this.baseOperation1();
10-
this.requiredOperations1();
11-
this.baseOperation2();
12-
this.hook1();
13-
this.requiredOperation2();
14-
this.baseOperation3();
15-
this.hook2();
36+
this.BaseOperation1();
37+
this.RequiredOperations1();
38+
this.BaseOperation2();
39+
this.Hook1();
40+
this.RequiredOperation2();
41+
this.BaseOperation3();
42+
this.Hook2();
1643
}
1744

18-
protected void baseOperation1()
45+
// EN: These operations already have implementations.
46+
//
47+
// RU: Эти операции уже имеют реализации.
48+
protected void BaseOperation1()
1949
{
20-
Console.Write("AbstractClass says: I am doing the bulk of the work\n");
50+
Console.WriteLine("AbstractClass says: I am doing the bulk of the work");
2151
}
2252

23-
protected void baseOperation2()
53+
protected void BaseOperation2()
2454
{
25-
Console.Write("AbstractClass says: But I let subclasses override some operations\n");
55+
Console.WriteLine("AbstractClass says: But I let subclasses override some operations");
2656
}
2757

28-
protected void baseOperation3()
58+
protected void BaseOperation3()
2959
{
30-
Console.Write("AbstractClass says: But I am doing the bulk of the work anyway\n");
60+
Console.WriteLine("AbstractClass says: But I am doing the bulk of the work anyway");
3161
}
32-
33-
protected abstract void requiredOperations1();
34-
35-
protected abstract void requiredOperation2();
36-
37-
protected virtual void hook1() { }
38-
39-
protected virtual void hook2() { }
62+
63+
// EN: These operations have to be implemented in subclasses.
64+
//
65+
// RU: А эти операции должны быть реализованы в подклассах.
66+
protected abstract void RequiredOperations1();
67+
68+
protected abstract void RequiredOperation2();
69+
70+
// EN: These are "hooks." Subclasses may override them, but it's not
71+
// mandatory since the hooks already have default (but empty)
72+
// implementation. Hooks provide additional extension points in some crucial
73+
// places of the algorithm.
74+
//
75+
// RU: Это «хуки». Подклассы могут переопределять их, но это не обязательно,
76+
// поскольку у хуков уже есть стандартная (но пустая) реализация. Хуки
77+
// предоставляют дополнительные точки расширения в некоторых критических
78+
// местах алгоритма.
79+
protected virtual void Hook1() { }
80+
81+
protected virtual void Hook2() { }
4082
}
4183

84+
// EN: Concrete classes have to implement all abstract operations of the base
85+
// class. They can also override some operations with a default implementation.
86+
//
87+
// RU: Конкретные классы должны реализовать все абстрактные операции базового
88+
// класса. Они также могут переопределить некоторые операции с реализацией по
89+
// умолчанию.
4290
class ConcreteClass1 : AbstractClass
4391
{
44-
protected override void requiredOperations1()
92+
protected override void RequiredOperations1()
4593
{
46-
Console.Write("ConcreteClass1 says: Implemented Operation1\n");
94+
Console.WriteLine("ConcreteClass1 says: Implemented Operation1");
4795
}
4896

49-
protected override void requiredOperation2()
97+
protected override void RequiredOperation2()
5098
{
51-
Console.Write("ConcreteClass1 says: Implemented Operation2\n");
99+
Console.WriteLine("ConcreteClass1 says: Implemented Operation2");
52100
}
53101
}
54102

103+
// EN: Usually, concrete classes override only a fraction of base class'
104+
// operations.
105+
//
106+
// RU: Обычно конкретные классы переопределяют только часть операций базового
107+
// класса.
55108
class ConcreteClass2 : AbstractClass
56109
{
57-
protected override void requiredOperations1()
110+
protected override void RequiredOperations1()
58111
{
59-
Console.Write("ConcreteClass2 says: Implemented Operation1\n");
112+
Console.WriteLine("ConcreteClass2 says: Implemented Operation1");
60113
}
61114

62-
protected override void requiredOperation2()
115+
protected override void RequiredOperation2()
63116
{
64-
Console.Write("ConcreteClass2 says: Implemented Operation2\n");
117+
Console.WriteLine("ConcreteClass2 says: Implemented Operation2");
65118
}
66119

67-
protected override void hook1()
120+
protected override void Hook1()
68121
{
69-
Console.Write("ConcreteClass2 says: Overridden Hook1\n");
122+
Console.WriteLine("ConcreteClass2 says: Overridden Hook1");
70123
}
71124
}
72125

73126
class Client
74127
{
75-
public static void ClientCode(AbstractClass ac)
128+
// EN: The client code calls the template method to execute the algorithm.
129+
// Client code does not have to know the concrete class of an object it works
130+
// with, as long as it works with objects through the interface of their base
131+
// class.
132+
//
133+
// RU: Клиентский код вызывает шаблонный метод для выполнения алгоритма.
134+
// Клиентский код не должен знать конкретный класс объекта, с которым работает,
135+
// при условии, что он работает с объектами через интерфейс их базового класса.
136+
public static void ClientCode(AbstractClass abstractClass)
76137
{
77-
ac.templateMethod();
138+
// ...
139+
abstractClass.TemplateMethod();
140+
// ...
78141
}
79142
}
80143

81144
class Program
82145
{
83146
static void Main(string[] args)
84147
{
85-
Console.Write("Same client code can work with different subclasses:\n");
148+
Console.WriteLine("Same client code can work with different subclasses:");
86149

87150
Client.ClientCode(new ConcreteClass1());
88151

89152
Console.Write("\n");
90-
Console.Write("Same client code can work with different subclasses:\n");
153+
154+
Console.WriteLine("Same client code can work with different subclasses:");
91155
Client.ClientCode(new ConcreteClass2());
92156
}
93157
}

0 commit comments

Comments
 (0)