Назад к вопросам
Middle+
69
questionbank
Что такое паттерн 'Хранитель' (Memento) и в каких ситуациях его целесообразно использовать?
Sobes Copilot
Получайте ответы в реальном времени
Ответ от нейросети
sobes.tech AI
Паттерн "Хранитель" (Memento) позволяет сохранить и восстановить предыдущее состояние объекта, не нарушая инкапсуляцию.
Применимость:
- Когда необходимо сохранить состояние объекта для последующего восстановления.
- Когда прямое сохранение состояния нарушило бы инкапсуляцию объекта.
Основные участники:
- Исходник (Originator): Объект, состояние которого нужно сохранить. Создает снимок (Memento) своего текущего состояния и восстанавливается из него.
- Снимок (Memento): Объект, хранящий состояние Исходника. Предоставляет интерфейс для доступа к состоянию, ограниченный только теми, кто должен его знать.
- Опекун (Caretaker): Хранит снимки. Не знает о внутреннем устройстве Исходника и не работает со снимками напрямую, только передает их.
Пример:
class Memento:
def __init__(self, state):
self._state = state
def get_state(self):
return self._state
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._generate_random_string()
print(f"Originator: And 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 after restoring from Memento: {self._state}")
def _generate_random_string(self):
# Имитация изменения состояния
import random
import string
return ''.join(random.choices(string.ascii_uppercase + string.digits, k=10))
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:
return
memento = self._mementos.pop()
print(f"Caretaker: Restoring state to: {memento.get_state()}")
try:
self._originator.restore(memento)
except Exception:
self.undo() # Если восстановление не удалось, пробуем предыдущий Memento
def show_history(self):
print("Caretaker: Here's the list of mementos:")
for memento in self._mementos:
print(memento.get_state())
# Использование
originator = Originator("SuperState")
caretaker = Caretaker(originator)
caretaker.backup()
originator.do_something()
caretaker.backup()
originator.do_something()
caretaker.backup()
originator.do_something()
print("\n")
caretaker.show_history()
print("\nClient: Now, let's undo!")
caretaker.undo()
print("\nClient: Once more!")
caretaker.undo()