Хранитель (шаблон проектирования): различия между версиями

[непроверенная версия][непроверенная версия]
Содержимое удалено Содержимое добавлено
Нет описания правки
Строка 15:
 
Позволяет не нарушая [[инкапсуляция|инкапсуляцию]] зафиксировать и сохранить внутреннее состояния объекта так, чтобы позднее восстановить его в этом состоянии.
 
Существует два возможных варианта реализации данного шаблона: классический, описанный в книге [[Design Patterns]], и реже встречаемый нестандартный вариант.
 
== Применение ==
Строка 23 ⟶ 25 :
 
== Структура ==
Классический вариант:
[[Файл:Memento design pattern.png|center|frame|[[UML]] диаграмма, описывающая шаблон Хранитель]]
[[Файл:Memento design pattern.png|center|frame|[[UML]] диаграмма, описывающая классический вариант шаблона Хранитель]]
 
Нестандартный вариант:
 
* '''Originator''' - "Создатель"
* '''Caretaker''' - "Опекун"
* '''Memento''' - "Хранитель"
 
== Описание ==
 
Классический вариант:
Шаблон Хранитель используется двумя объектами: "Создателем" (originator) и "Опекуном" (caretaker). "Создатель" - это объект, у которого есть внутреннее состояние. Объект "Опекун" может производить некоторые действия с "Создателем", но при этом необходимо иметь возможность восстановить изменения. Для этого "Опекун" запрашивает у "Создателя" объект "Хранителя". Затем выполняет запланированное действие (или последовательность действий). Для выполнения отката "Создателя" к состоянию, которое предшествовало изменениям, "Опекун" возвращает объект "Хранителя" его "Создателю". "Хранитель" является непрозрачным (т.е. таким, который не может или не должен изменяться "Опекуном").
 
Нестандартный вариант:
Отличие данного варианта от классического заключено в более жёстком ограничении на доступ "Опекуна" к внутреннему состоянию "Создателя". В классическом варианте у "Опекуна" есть потенциальная возможность получить доступ к внутренним данным "Создателя" через "Хранителя", изменить состояние и установить его обратно "Создателю". В данном варианте "Опекун" обладает возможностью лишь восстановить состояние "Хранителя", вызвав Restore. Кроме всего прочего, "Опекуну" не требуется владеть связью на "Хранителя", чтобы восстановить его состояние. Это позволяет сохранять и восстанавливать состояние сложных иерархических или сетевых структур (состояния объектов и всех связей между ними) путём сбора снимков всех зарегистрированных объектов системы.
 
== Примеры реализации ==
 
Первый вариант шаблона:
<source lang="csharp">
//This structural code demonstrates the Memento pattern which temporary saves and restores another object's internal state.
Строка 260 ⟶ 271 :
</source>
 
Нестандартный вариант шаблона:
<source lang="csharp">
public interface IShape
{
void Draw();
}
 
public interface IMemento
{
void RestoreState();
}
 
public interface IOriginator
{
IMemento GetState();
}
 
public class CircleOriginator : IShape, IOriginator
{
private class CircleMemento : IMemento
{
private readonly double r;
private readonly CircleOriginator originator;
 
public CircleMemento(CircleOriginator originator)
{
this.originator = originator;
r = originator.r;
}
 
public void Restore()
{
originator.r = r;
}
}
 
double r;
 
public void CircleOriginator(double r)
{
this.r = r;
}
 
public void Draw()
{
Console.WriteLine("Circle {0}", r);
}
 
public CircleMemento GetState()
{
return new CircleMemento(this);
}
}
 
public class RectOriginator : IShape, IOriginator
{
private class RectMemento : IMemento
{
private readonly double w;
private readonly double h;
private readonly RectOriginator originator;
 
public RectMemento(RectOriginator originator)
{
this.originator = originator;
w = originator.w;
h = originator.h;
}
 
public void Restore()
{
originator.w = w;
originator.h = h;
}
}
 
double w;
double h;
 
public void RectOriginator(double w, double h)
{
this.w = w;
this.h = h;
}
 
public void Draw()
{
Console.WriteLine("Rectangle {0}x{1}", w, h);
}
 
public IMemento GetState()
{
return new RectMemento(this);
}
}
 
</source>
== Ссылки ==
*[http://cpp-reference.ru/patterns/behavioral-patterns/memento/ Паттерн Memento (хранитель)] — назначение, описание, особенности и реализация на С++.