Меню

Главная
Случайная статья
Настройки
Хранитель (шаблон проектирования)
Материал из https://ru.wikipedia.org

Хранитель (англ. Memento) — поведенческий шаблон проектирования, позволяющий, не нарушая инкапсуляцию, зафиксировать и сохранить внутреннее состояние объекта так, чтобы позднее восстановить его в это состояние.

Существует два возможных варианта реализации данного шаблона: классический, описанный в книге Design Patterns, и реже встречающийся нестандартный вариант.

Содержание

Применение

Шаблон Хранитель используется, когда:
  • необходимо сохранить снимок состояния объекта (или его части) для последующего восстановления
  • прямой интерфейс получения состояния объекта раскрывает детали реализации и нарушает инкапсуляцию объекта


Структура

Классический вариант:

Нестандартный вариант:
  • Originator — «Создатель»
  • Caretaker — «Опекун»
  • Memento — «Хранитель»


Описание

Классический вариант: Шаблон Хранитель используется двумя объектами: «Создателем» (originator) и «Опекуном» (caretaker). «Создатель» — это объект, у которого есть внутреннее состояние. Объект «Опекун» может производить некоторые действия с «Создателем», но при этом необходимо иметь возможность откатить изменения. Для этого «Опекун» запрашивает у «Создателя» объект «Хранителя». Затем выполняет запланированное действие (или последовательность действий). Для выполнения отката «Создателя» к состоянию, которое предшествовало изменениям, «Опекун» возвращает объект «Хранителя» его «Создателю». «Хранитель» является непрозрачным (то есть таким, который не может или не должен изменяться «Опекуном»).

Нестандартный вариант: Отличие данного варианта от классического заключено в более жёстком ограничении на доступ «Опекуна» к внутреннему состоянию «Создателя». В классическом варианте у «Опекуна» есть потенциальная возможность получить доступ к внутренним данным «Создателя» через «Хранителя», изменить состояние и установить его обратно «Создателю». В данном варианте «Опекун» обладает возможностью лишь восстановить состояние «Хранителя», вызвав Restore. Кроме всего прочего, «Опекуну» не требуется владеть связью на «Хранителя», чтобы восстановить его состояние. Это позволяет сохранять и восстанавливать состояние сложных иерархических или сетевых структур (состояния объектов и всех связей между ними) путём сбора снимков всех зарегистрированных объектов системы.

Примеры реализации

Стандартный вариант шаблона на Python
class Memento:
    def __init__(self, state: str):
        self.__state = state

    def get_state(self) -> str:
        return self.__state


class Caretaker:
    def __init__(self, memento: Memento):
        self.__memento = memento

    def get_memento(self) -> Memento:
        return self.__memento


class Originator:
    def __init__(self, state: str):
        self.__state = state

    @property
    def state(self) -> str:
        return self.__state

    @state.setter
    def state(self, state: str) -> None:
        self.__state = state

    def save_state(self) -> Memento:
        return Memento(self.__state)

    def restore_state(self, memento: Memento) -> None:
        self.__state = memento.get_state()


if __name__ == '__main__':
    originator = Originator(state='on')
    print(originator.state)

    caretaker = Caretaker(originator.save_state())

    originator.state = 'off'
    print(originator.state)

    originator.restore_state(caretaker.get_memento())
    print(originator.state)


# on
# off
# on


Стандартный вариант шаблона на Java
Downgrade Counter