Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Design Patterns via C#.pdf
Скачиваний:
154
Добавлен:
17.03.2016
Размер:
13.25 Mб
Скачать

223

Паттерн Memento

Название

Хранитель

Также известен как

Token (Лексема)

Классификация

По цели: поведенческий По применимости: к объектам

Частота использования

Низкая

- 1 2 3 4 5

Назначение

Паттерн Memento - не нарушая инкапсуляции, фиксирует и выносит за пределы объекта-хозяина его внутреннее состояние так, чтобы позднее это вынесенное состояние можно было восстановить в исходном объекте-хозяине.

Введение

Воспользуемся метафорой для описания работы паттерна Memento. Представьте себе, что Вы приобрели робота ASIMO и отправились с ним на прогулку, дошли до городского пляжа и решили искупаться. Вы сняли с себя одежду, сложили одежду в рюкзак, отдали рюкзак роботу, а сами пошли в воду. Задача робота – стеречь рюкзак. Инженеры HONDA не пока еще научили ASIMO открывать рюкзаки, поэтому он не сможет получить доступ к вещам и, например, поменять Ваши джинсы на новый сервопривод или аккумулятор.

Поплавав, Вы вышли из воды на берег, взяли рюкзак у робота, достали из рюкзака одежду и одели одежду на себя.

Рассмотрим основных участников паттерна Memento:

224

Важно помнить, что состояние объекта – это набор значений полей этого объекта. Одежда человека может входить в понятие одной из разновидностей состояний человека, так как одежду можно описать в виде набора переменных, принадлежащих объекту-человеку. И зачастую, когда нас просят описать человека, то мы помимо биометрических данных, зачастую указываем фасон и цвет одежды в которую одет человек.

Человек (Man) – хозяин (сложный объект со сложной конфигурацией состояния), которому по ряду причин потребовалось изменить свое состояние «из одетого в раздетого», а потом восстановить свое состояние обратно в первоначальный вид «из раздетого в одетого».

Рюкзак (Backpack) – хранитель (объект для хранения в себе копии состояния хозяина). Рюкзак с одеждой (состоянием хозяина) переходит из рук хозяина в руки робота, а позднее обратно из рук робота в руки хозяина. Это удобно, потому что возможно у робота есть еще и сумка с предыдущим состоянием хозяина, например, со смокингом со вчерашнего посещения оперы.

Робот (Robot) – посыльный (объект для ношения рюкзаков и сумок с состояниями хозяина) в любой момент готов дать хозяину нужную сумку или рюкзак с определенным набором вещей (предыдущие состояния). Человеку не требуется заботиться о поиске нужной конфигурации состояния, за него всю заботу за конфигурацию и хранение состояний берет на себя робот.

Из сказанного выше легко сформировать модель и реализовать ее программно.

class Program

 

 

 

 

 

 

{

 

 

 

 

 

 

static void Main()

 

 

 

 

 

{

 

 

 

 

 

 

Man David =

new Man();

 

 

 

 

Robot ASIMO

= new Robot();

 

 

 

 

David.Сlothes

= "Футболка, Джинсы, Кеды";

 

 

 

ASIMO.Backpack = David.Undress();

 

 

 

David.Сlothes

= "Шорты спортивные";

 

 

 

David.Dress(ASIMO.Backpack);

 

 

 

 

}

 

 

 

 

 

 

}

 

 

 

 

 

 

class Man

 

 

 

class Backpack

 

 

{

 

 

 

 

 

 

 

 

{

 

 

public string Сlothes { get; set;

}

 

 

public string

Сontents

 

 

 

 

 

class Robot

 

 

 

 

{

 

public void Dress(Backpack backpack)

 

{

get;

 

{

 

 

 

 

public Backpack Backpack

 

 

 

private set;

Сlothes = backpack.Сontents;

 

{

 

}

 

}

 

 

 

 

get;

 

 

 

 

 

 

 

 

 

public Backpack(string сontents)

set;

public Backpack Undress()

 

}

 

{

 

{

 

 

 

 

}

 

 

 

this.Сontents = сontents;

return new Backpack(Сlothes);

 

 

 

}

 

 

}

 

 

 

 

 

 

 

 

}

 

 

}

 

 

 

 

 

 

 

 

 

 

 

См. Пример к главе: \018_Memento\002_Memento

225

Структура паттерна на языке UML

См. Пример к главе: \018_Memento\001_Memento

Структура паттерна на языке C#

class Program

{

static void Main()

{

Originator originator = new Originator(); originator.State = "On";

Caretaker caretaker = new Caretaker(); caretaker.Memento = originator.CreateMemento();

originator.State = "Off";

originator.SetMemento(caretaker.Memento);

}

}

class Originator

{

public string State { get; set; }

public void SetMemento(Memento memento)

{

State = memento.State;

}

public Memento CreateMemento()

{

return new Memento(State);

}

}

class Memento

{

public string State

{

get; private set;

}

public Memento(string state)

{

this.State = state;

}

}

См. Пример к главе: \018_Memento\001_Memento

class Caretaker

{

public Memento Memento

{

get; set;

}

}

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]