Сегодня мы запускаем еще один шаблон проектирования, он называется Memento, это очень простой для понимания шаблон, также основной рисунок в этой статье также переводит шаблон, в то же время очень привлекающий внимание :) в основном это означает, что вы можете восстановить состояние объекта к предыдущему, точнее схема объяснена далее в статье :)

Обсуждение

Основная цель шаблона Memento - сохранить внутреннее состояние объекта и возможность его восстановления при необходимости без нарушения инкапсуляции.

Реализация этого паттерна состоит в основном из трех классов:

Originator- класс, который сохраняет и восстанавливает состояние объекта.

Смотритель - класс, который хранит все состояния объекта, с которым он работает, возвращает эти состояния и добавляет новые состояния объекта.

Memento- класс, в котором хранится текущее состояние объекта, его состояние может быть прочитано классом Originator.

Отличным примером использования шаблона Memento является, например, восстановление предыдущих версий плагинов в wordpress, если вы использовали wordpress и у вас был установлен плагин WP Rollback, это была новая кнопка рядом с названием плагина Откат , который используется для восстановления предыдущей версии плагина, как показано на рисунке ниже.

Создатели этого плагина использовали паттерн Memento на 100% :) Memento также используется в играх, когда игрок хочет загрузить предыдущее состояние ранее сохраненной игры.

Намерение

  • Сохранение внутреннего состояния объекта и, при необходимости, восстановление ранее сохраненного состояния объекта.
  • Отсутствие нарушения инкапсуляции объекта, над которым мы работаем.

Проблема

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

Эти зрелые люди знают, что происходит на картинке выше 😂😂

Используйте, когда:

  • Вам необходимо восстановить состояние объекта до его предыдущего состояния.

Структура

UML-диаграмма паттерна сувениров выглядит так:

Объяснение работы этих классов уже есть в разделе Обсуждение вверху статьи, так что мне, наверное, не придется повторяться :)

Я знаю, ты очень умный

Впрочем, пора перейти к коду :) Для реальной работы :)

Начнем с класса Memento.

namespace MementoScheme
{
    class Memento
    {
        private string state;
        public Memento(string state)
        {
            this.state = state;
        }
        public string getState()
        {
            return state;
        }
    }
}

Как видите, этот класс, как объяснялось ранее, хранит и возвращает текущее состояние объекта.

Смотритель класс.

namespace MementoScheme
{
    class Caretaker
    {
        private List<Memento> mementos = new List<Memento>();
        public void addMemento(Memento m)
        {
            mementos.Add(m);
        }
        public Memento getMemento(int index)
        {
            return mementos[index];
        }
    }
}

И класс Originator.

namespace MementoScheme
{
    class Originator
    {
        private string state;
        public void setState(string state)
        {
            Console.WriteLine("Originator: Setting state to " + state);
            this.state = state;
        }
        public Memento save()
        {
            Console.WriteLine("Originator: Saving to Memento.");
            return new Memento(state);
        }
        public void restore(Memento m)
        {
            state = m.getState();
            Console.WriteLine("Originator: State after restoring from Memento: " + state);
        }
    }
}

Как уже было сказано ранее, у этого класса, как видите, есть методы, отвечающие за сохранение и восстановление состояния объекта. В методе save () нам нужно получить текущее состояние объекта, поэтому мы должны использовать класс Memento, аналогичный классу the restore () метод.

Еще раз повторяю, объяснение функции всех этих классов находится в разделе Обсуждение вверху статьи :)

Конечно, остался заказчик, который пользуется этими классами.

namespace MementoScheme
{
    public class MementoDemo
    {
        public static void Main(String[] args)
        {
            Caretaker caretaker = new Caretaker();
            Originator originator = new Originator();
            originator.setState("State1");
            originator.setState("State2");
            caretaker.addMemento(originator.save());
            originator.setState("State3");
            caretaker.addMemento(originator.save());
            originator.setState("State4");
            originator.restore(caretaker.getMemento(1));
            Console.ReadLine();
        }
    }
}

Результат:

Пример из реальной жизни

Замена тормозного барабана

Предположим, нам нужно заменить тормозной барабан в машине, и он должен сделать за нас робота.

Требуется подорвать машину и снять колесо, затем заменить тормозной барабан и вернуться в предыдущее состояние, чтобы поставить колесо и нормально поставить машину :) В роботе, который должен это сделать за нас, будет хорошо загрузить программное обеспечение с использованием выкройки Memento :) Для лучшего понимания приведена картинка ниже.

И снова к коду :) Давайте сделаем это по порядку, как в предыдущем примере :) В общем, код мне не понадобится, даже вроде как мне объяснять, потому что он практически такой же, как в предыдущем примере, только имена разные :)

Итак, мы начнем с класса Memento, в нашем случае он называется Автомобиль.

namespace Mechanic
{
    class Car
    {
        private string state;
        public Car(string state)
        {
            this.state = state;
        }
        public string getState()
        {
            return state;
        }
    }
}

Вы можете видеть, что так же, как и раньше, отличается только название класса :)

Смотритель класс.

namespace Mechanic
{
    class Caretaker
    {
        private List<Car> mementos = new List<Car>();
        public void addMemento(Car m)
        {
            mementos.Add(m);
        }
        public Car getMemento(int index)
        {
            return mementos[index];
        }
    }
}

Как и раньше, только имена тоже разные :)

Класс Originator в нашем случае называется Mechanic.

namespace Mechanic
{
    class Mechanic
    {
        private string state;
        public void setState(string state)
        {
            Console.WriteLine(state);
            this.state = state;
        }
        public Car save()
        {
            return new Car(state);
        }
        public void restore(Car m)
        {
            state = m.getState();
            Console.WriteLine("Returning to the previous work.");
            Console.WriteLine(state);
        }
    }
}

Логика этого класса такая же, как и в предыдущем примере :)

И клиент :)

namespace Mechanic
{
    class Program
    {
        static void Main(string[] args)
        {
            Caretaker caretaker = new Caretaker();
            Mechanic mechanic = new Mechanic();
            mechanic.setState("The brake drum is in use. Begin of work");
            caretaker.addMemento(mechanic.save());
            mechanic.setState("The brake drum is available to use. End of work");
            mechanic.restore(caretaker.getMemento(0));
            Console.ReadLine();
        }
    }
}

Результат:

Отношения с другими шаблонами проектирования

  • Memento иногда используется вместе с итератором для управления состоянием итерации.

Резюме

Это все о Memento 🙂.

Ссылка на github со всем кодом из этой статьи: https://github.com/Slaw145/Memento

Этот контент вы также можете найти в моем блоге devman.pl: http://devman.pl/programtech/design-patterns-memento/

И на steemit: https://steemit.com/design-patterns/@slawas/design-patterns-memento

В следующей статье мы поговорим о шаблоне Memento.

И ОБЯЗАТЕЛЬНО присоединяйтесь к сообществу DevmanCommunity на fb, часть сообщества находится в одном месте 🙂

- сайт в фб: Devman.pl-Slawomir Kowalski

- группа в фб: DevmanCommunity

Спрашивайте, комментируйте внизу в конце поста, делитесь им, оценивайте, как хотите🙂.

Иллюстрации, изображения и диаграммы взяты с сайта: https://sourcemaking.com/design_patterns/memento