
- •А.А. Волосевич
- •3. Шаблоны и архитектура программ
- •3.1. Модульное тестирование
- •3.2. Шаблоны проектирования
- •3.3. Структурные шаблоны: Декоратор, Заместитель, мост Декоратор (Decorator)
- •Заместитель (Proxy)
- •Мост (Bridge)
- •3.4. Структурные шаблоны: компоновщик и приспособленец Компоновщик (Composite)
- •Приспособленец (Flyweight)
- •3.5. Структурные шаблоны: адаптер и фасад Адаптер (Adapter)
- •Фасад (Façade)
- •3.6. Порождающие шаблоны: прототип, фабричный метод, одиночка Прототип (Prototype)
- •Фабричный метод (Factory method)
- •Одиночка (Singleton)
- •3.7. Порождающие шаблоны: абстрактная фабрика и строитель Абстрактная фабрика (Abstract factory)
- •Строитель (Builder)
- •3.8. Шаблоны поведения: стратегия, состояние, шаблонный метод Стратегия (Strategy)
- •Состояние (State)
- •Шаблонный метод (Template method)
- •3.9. Шаблоны поведения: цепочка обязанностей и команда Цепочка обязанностей (Chain of responsibility)
- •Команда (Command)
- •3.10. Шаблоны поведения: итератор, посредник, наблюдатель Итератор (Iterator)
- •Посредник (Mediator)
- •Наблюдатель (Observer)
- •3.11. Шаблоны поведения: посетитель, интерпретатор, хранитель Посетитель (Visitor)
- •Интерпретатор (Interpreter)
- •Хранитель (Memento)
- •3.12. Некоторые неклассические шаблоны проектирования
- •Неизменный объект (Immutable object)
- •Пул объектов (Object pool)
- •Отложенная инициализация (Lazy initialization)
- •Нулевой объект (Null object)
- •3.13. Антипаттерны
- •3.14. Архитектура прогРаммного Обеспечения
- •«Клиент-сервер»
- •Архитектура, основанная на использовании компонентов
- •Многоуровневая архитектура
- •Шина сообщений
- •Выделенное представление
- •Объектно-ориентированная архитектура
- •Архитектура, ориентированная на сервисы
Хранитель (Memento)
Этот шаблон используется для захвата и сохранения внутреннего состояния объекта с возможностью дальнейшего восстановления состояния. Важной особенностью шаблона Хранитель является то, что он позволяет сохранить внутреннее состояние объекта без нарушения правил инкапсуляции.
Рис. 23. UML-диаграмма шаблона Хранитель.
На рис. 23 показана UML-диаграмма шаблона хранитель. Ниже описаны элементы диаграммы.
Составитель. Этот тот класс, состояние которого предполагается сохранять. Составитель включает метод CreateMemento(), который используется для генерации объекта-хранителя, содержащего состояние составителя. Также составитель содержит метод SetMemento(), восстанавливающий состояние по хранителю.
Хранитель. Объект-хранитель содержит информацию о состоянии Составителя. То, что содержит Хранитель, контролируется Составителем. Хранитель защищает сохраняемую информацию, предоставляя усеченный внешний интерфейс, не позволяющий эту информацию редактировать.
Смотритель. Класс Смотритель используется для хранения объектов-хранителей для дальнейшего использования. Смотритель используется только для хранения – он не просматривает и не изменяет внутренне состояние Хранителей. Смотритель может содержать как единичный объект-хранитель, так и коллекцию хранителей.
Рассмотрим пример реализации шаблона Хранитель. В примере описывается набор классов для поддержки функции Undo в библиотечной системе. Класс-составитель представляет информацию о книге, редактируемую пользователем. Если пользователь делает ошибку, он может выполнить операцию Undo для возврата книги в первоначальное состояние.
public class Book
{
private string _isbn;
private string _title;
private string _author;
private DateTime _lastEdited;
public string ISBN
{
get { return _isbn; }
set
{
_isbn = value;
SetLastEdited();
}
}
public string Title
{
get { return _title; }
set
{
_title = value;
SetLastEdited();
}
}
public string Author
{
get { return _author; }
set
{
_author = value;
SetLastEdited();
}
}
public Book()
{
SetLastEdited();
}
private void SetLastEdited()
{
_lastEdited = DateTime.UtcNow;
}
public Memento CreateUndo()
{
return new Memento(_isbn, _title, _author, _lastEdited);
}
public void RestoreFromUndo(Memento memento)
{
_title = memento.Title;
_author = memento.Author;
_isbn = memento.ISBN;
_lastEdited = memento.LastEdited;
}
public void ShowBook()
{
Console.WriteLine("{0} - '{1}' by {2}, edited {3}.",
ISBN, Title, Author, _lastEdited);
}
}
public class Memento
{
public string ISBN { get; private set; }
public string Title { get; private set; }
public string Author { get; private set; }
public DateTime LastEdited { get; private set; }
public Memento(string isbn, string title, string author,
DateTime lastEdited)
{
ISBN = isbn;
Title = title;
Author = author;
LastEdited = lastEdited;
}
}