Sobes.tech
Middle+

Какво е моделът 'Memento' и в кои ситуации е целесъобразно да го използвате?

sobes.tech AI

Отговор от 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"Произход: Начално състояние: {self._state}")

    def do_something(self):
        print("Произход: Правя нещо важно.")
        self._state = self._generate_random_string()
        print(f"Произход: Състоянието ми се промени на: {self._state}")

    def save(self):
        print("Произход: Запазване в Мемо.")
        return Memento(self._state)

    def restore(self, memento):
        self._state = memento.get_state()
        print(f"Произход: Състояние след възстановяване от Мемо: {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("\nПазител: Запазване на състоянието на Произхода...")
        self._mementos.append(self._originator.save())

    def undo(self):
        if not self._mementos:
            return

        memento = self._mementos.pop()
        print(f"Пазител: Възстановяване на състоянието към: {memento.get_state()}")
        try:
            self._originator.restore(memento)
        except Exception:
            self.undo() # Ако възстановяването не успее, опитва предишен Мемо

    def show_history(self):
        print("Пазител: Списък с мемо" )
        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("\nКлиент: Сега, нека отменим!")
caretaker.undo()

print("\nКлиент: Още веднъж!")
caretaker.undo()