Skip to content

Commit 5fa01ea

Browse files
committed
Memento: improve conceptual example
1 parent d33754b commit 5fa01ea

File tree

1 file changed

+125
-57
lines changed

1 file changed

+125
-57
lines changed

Memento.Conceptual/Program.cs

Lines changed: 125 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -1,36 +1,66 @@
1-
using System;
1+
// EN: Memento Design Pattern
2+
//
3+
// Intent: Capture and externalize an object's internal state so that the object
4+
// can be restored to this state later, without violating encapsulation.
5+
//
6+
// RU: Паттерн Снимок
7+
//
8+
// Назначение: Фиксирует и восстанавливает внутреннее состояние объекта таким
9+
// образом, чтобы в дальнейшем объект можно было восстановить в этом состоянии
10+
// без нарушения инкапсуляции.
11+
12+
using System;
213
using System.Collections.Generic;
314
using System.Linq;
415
using System.Threading;
516

617
namespace RefactoringGuru.DesignPatterns.Memento.Conceptual
718
{
19+
// EN: The Originator holds some important state that may change over time.
20+
// It also defines a method for saving the state inside a memento and
21+
// another method for restoring the state from it.
22+
//
23+
// RU: Создатель содержит некоторое важное состояние, которое может со
24+
// временем меняться. Он также объявляет метод сохранения состояния внутри
25+
// снимка и метод восстановления состояния из него.
826
class Originator
927
{
10-
string _state;
28+
//
29+
// EN: For the sake of simplicity, the originator's state is
30+
// stored inside a single variable.
31+
//
32+
// RU: Для удобства состояние создателя хранится внутри одной
33+
// переменной.
34+
private string _state;
1135

1236
public Originator(string state)
1337
{
1438
this._state = state;
15-
Console.Write("Originator: My initial state is: " + _state + "\n");
39+
Console.WriteLine("Originator: My initial state is: " + state);
1640
}
1741

18-
public void doSomething()
42+
// EN: The Originator's business logic may affect its internal state.
43+
// Therefore, the client should backup the state before launching
44+
// methods of the business logic via the save() method.
45+
//
46+
// RU: Бизнес-логика Создателя может повлиять на его внутреннее
47+
// состояние. Поэтому клиент должен выполнить резервное копирование
48+
// состояния с помощью метода save перед запуском методов бизнес-логики.
49+
public void DoSomething()
1950
{
20-
Console.Write("Originator: I'm doing something important.\n");
21-
this._state = this.generateRandomString(30);
22-
Console.Write($"Originator: and my state has changed to: {_state}\n");
51+
Console.WriteLine("Originator: I'm doing something important.");
52+
this._state = this.GenerateRandomString(30);
53+
Console.WriteLine($"Originator: and my state has changed to: {_state}");
2354
}
2455

25-
private string generateRandomString(int length = 10)
56+
private string GenerateRandomString(int length = 10)
2657
{
27-
string allowedSymbs = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
28-
58+
string allowedSymbols = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
2959
string result = string.Empty;
3060

31-
while(length > 0)
61+
while (length > 0)
3262
{
33-
result += allowedSymbs[new Random().Next(0, allowedSymbs.Length)];
63+
result += allowedSymbols[new Random().Next(0, allowedSymbols.Length)];
3464

3565
Thread.Sleep(12);
3666

@@ -40,32 +70,50 @@ private string generateRandomString(int length = 10)
4070
return result;
4171
}
4272

43-
public Memento save()
73+
// EN: Saves the current state inside a memento.
74+
//
75+
// RU: Сохраняет текущее состояние внутри снимка.
76+
public Memento Save()
4477
{
4578
return new ConcreteMemento(this._state);
4679
}
4780

48-
public void restore(Memento memento)
81+
// EN: Restores the Originator's state from a memento object.
82+
//
83+
// RU: Восстанавливает состояние Создателя из объекта снимка.
84+
public void Restore(Memento memento)
4985
{
5086
if (!(memento is ConcreteMemento))
5187
{
5288
throw new Exception("Unknown memento class " + memento.ToString());
5389
}
5490

55-
this._state = memento.getState();
91+
this._state = memento.GetState();
5692
Console.Write($"Originator: My state has changed to: {_state}");
5793
}
5894
}
5995

96+
// EN: The Memento interface provides a way to retrieve the memento's
97+
// metadata, such as creation date or name. However, it doesn't expose the
98+
// Originator's state.
99+
//
100+
// RU: Интерфейс Снимка предоставляет способ извлечения метаданных снимка,
101+
// таких как дата создания или название. Однако он не раскрывает состояние
102+
// Создателя.
60103
interface Memento
61104
{
62-
string getName();
105+
string GetName();
63106

64-
string getState();
107+
string GetState();
65108

66-
DateTime getDate();
109+
DateTime GetDate();
67110
}
68111

112+
// EN: The Concrete Memento contains the infrastructure for storing the
113+
// Originator's state.
114+
//
115+
// RU: Конкретный снимок содержит инфраструктуру для хранения состояния
116+
// Создателя.
69117
class ConcreteMemento : Memento
70118
{
71119
private string _state;
@@ -78,106 +126,126 @@ public ConcreteMemento(string state)
78126
this._date = DateTime.Now;
79127
}
80128

81-
public string getState()
129+
// EN: The Originator uses this method when restoring its state.
130+
//
131+
// RU: Создатель использует этот метод, когда восстанавливает своё
132+
// состояние.
133+
public string GetState()
82134
{
83135
return this._state;
84136
}
85-
86-
public string getName()
137+
138+
// EN: The rest of the methods are used by the Caretaker to display
139+
// metadata.
140+
//
141+
// RU: Остальные методы используются Опекуном для отображения
142+
// метаданных.
143+
public string GetName()
87144
{
88-
return this._date + " / (" + _state.Substring(0, 9) + "...)";
145+
return $"{this._date} / ({this._state.Substring(0, 9)})...";
89146
}
90147

91-
public DateTime getDate()
148+
public DateTime GetDate()
92149
{
93150
return this._date;
94151
}
95152
}
96153

154+
// EN: The Caretaker doesn't depend on the Concrete Memento class.
155+
// Therefore, it doesn't have access to the originator's state, stored
156+
// inside the memento. It works with all mementos via the base Memento
157+
// interface.
158+
//
159+
// RU: Опекун не зависит от класса Конкретного Снимка. Таким образом, он не
160+
// имеет доступа к состоянию создателя, хранящемуся внутри снимка. Он
161+
// работает со всеми снимками через базовый интерфейс Снимка.
97162
class Caretaker
98163
{
99164
private List<Memento> _mementos = new List<Memento>();
100165

101-
private Originator originator = null;
166+
private Originator _originator = null;
102167

103168
public Caretaker(Originator originator)
104169
{
105-
this.originator = originator;
170+
this._originator = originator;
106171
}
107172

108-
public void backup()
173+
public void Backup()
109174
{
110-
Console.Write("\nCaretaker: Saving Originator's state...\n");
111-
this._mementos.Add(this.originator.save());
175+
Console.WriteLine("\nCaretaker: Saving Originator's state...");
176+
this._mementos.Add(this._originator.Save());
112177
}
113178

114-
public void undo()
179+
public void Undo()
115180
{
116-
if (_mementos.Count == 0)
181+
if (this._mementos.Count == 0)
117182
{
118183
return;
119184
}
120185

121-
var memento = _mementos.Last();
122-
_mementos.Remove(memento);
186+
var memento = this._mementos.Last();
187+
this._mementos.Remove(memento);
123188

124-
Console.Write("Caretaker: Restoring state to: " + memento.getName() + "\n");
189+
Console.WriteLine("Caretaker: Restoring state to: " + memento.GetName());
125190

126191
try
127192
{
128-
this.originator.restore(memento);
193+
this._originator.Restore(memento);
129194
}
130-
catch(Exception)
195+
catch (Exception)
131196
{
132-
this.undo();
197+
this.Undo();
133198
}
134199
}
135200

136-
public void showHistory()
201+
public void ShowHistory()
137202
{
138-
Console.Write("Caretaker: Here's the list of mementos:\n");
203+
Console.WriteLine("Caretaker: Here's the list of mementos:");
139204

140-
foreach (var memento in _mementos)
205+
foreach (var memento in this._mementos)
141206
{
142-
Console.Write(memento.getName() + "\n");
207+
Console.WriteLine(memento.GetName());
143208
}
144209
}
145210
}
146211

147-
class Program
148-
{
149-
static void Main(string[] args)
150-
{
151-
Client.ClientCode();
152-
}
153-
}
154-
155212
class Client
156213
{
157214
public static void ClientCode()
158215
{
216+
// EN: Client code.
217+
//
218+
// RU: Клиентский код.
159219
Originator originator = new Originator("Super-duper-super-puper-super.");
160220
Caretaker caretaker = new Caretaker(originator);
161221

162-
caretaker.backup();
163-
originator.doSomething();
222+
caretaker.Backup();
223+
originator.DoSomething();
164224

165-
caretaker.backup();
166-
originator.doSomething();
225+
caretaker.Backup();
226+
originator.DoSomething();
167227

168-
caretaker.backup();
169-
originator.doSomething();
228+
caretaker.Backup();
229+
originator.DoSomething();
170230

171231
Console.WriteLine();
172-
caretaker.showHistory();
232+
caretaker.ShowHistory();
173233

174234
Console.Write("\nClient: Now, let's rollback!\n\n");
175-
caretaker.undo();
235+
caretaker.Undo();
176236

177237
Console.Write("\n\nClient: Once more!\n\n");
178-
caretaker.undo();
238+
caretaker.Undo();
179239

180240
Console.WriteLine();
181241
}
182242
}
243+
244+
class Program
245+
{
246+
static void Main(string[] args)
247+
{
248+
Client.ClientCode();
249+
}
250+
}
183251
}

0 commit comments

Comments
 (0)