Назад к вопросам
Middle+
70
questionbank
Что такое паттерн 'Хранитель' (Memento)?
Sobes Copilot
Получайте ответы в реальном времени
Ответ от нейросети
sobes.tech AI
Паттерн проектирования "Хранитель" (Memento) позволяет сохранить и восстановить предшествующие состояния объекта без раскрытия деталей его реализации.
Основные роли:
- Исходный объект (Originator): Объект, состояние которого нужно сохранить. Создает объект-хранитель и использует его для восстановления своего состояния.
- Хранитель (Memento): Объект, который хранит состояние исходного объекта. Должен предоставлять минимально возможный интерфейс для доступа к хранимому состоянию, чтобы защитить его целостность.
- Опекун (Caretaker): Отвечает за хранение хранителей. Запрашивает хранитель у исходного объекта и передает его обратно исходному объекту для восстановления. Опекун не взаимодействует напрямую с содержимым хранителя.
Принцип работы:
- Исходный объект создает хранитель, содержащий снимок своего текущего состояния.
- Опекун сохраняет этот хранитель (например, в списке).
- Когда нужно восстановить состояние исходного объекта, опекун передает сохраненный хранитель обратно исходному объекту.
- Исходный объект восстанавливает свое состояние из данных, хранящихся в хранителе.
Преимущества:
- Сохранение инкапсуляции исходного объекта.
- Позволяет реализовать механизмы отмены (undo) и возврата (redo).
- Упрощает управление состояниями объекта.
Недостатки:
- Создание хранителей может быть затратным по памяти, особенно для больших объектов.
- Состояние хранителя может быть сложным для управления.
Пример реализации (упрощенный):
# Исходный объект
class Originator:
def __init__(self, state):
self._state = state
print(f"Originator: Initial state is {self._state}")
def do_something(self):
print("Originator: I'm doing something important.")
self._state = self._state + "_changed" # Изменяем состояние
print(f"Originator: My state has changed to {self._state}")
def save(self):
print("Originator: Saving to Memento.")
return Memento(self._state) # Создаем хранитель
def restore(self, memento):
self._state = memento.get_state() # Восстанавливаем состояние из хранителя
print(f"Originator: State restored to {self._state}")
# Хранитель
class Memento:
def __init__(self, state):
self._state = state
def get_state(self):
return self._state
# Опекун
class Caretaker:
def __init__(self, originator):
self._originator = originator
self._mementos = []
def backup(self):
print("\nCaretaker: Saving Originator's state...")
self._mementos.append(self._originator.save())
def undo(self):
if not self._mementos:
print("\nCaretaker: No mementos to restore.")
return
memento = self._mementos.pop() # Берем последний хранитель
print(f"\nCaretaker: Restoring state to: {memento.get_state()}")
try:
self._originator.restore(memento)
except Exception:
self.undo() # В случае ошибки, пробуем предыдущий хранитель (опционально)
def show_history(self):
print("Caretaker: Here's the list of mementos:")
for memento in self._mementos:
print(memento.get_state())