1. Что такое паттерн Memento

Паттерн Memento - это поведенческий паттерн проектирования, используемый для сохранения и восстановления внутреннего состояния объекта. Он сохраняет состояние объекта в объекте memento, который может быть использован для восстановления объекта до предыдущего состояния в будущем.

2. Характеристики и преимущества паттерна Memento

Характеристики и преимущества паттерна Memento включают:

  • Способность сохранять и восстанавливать внутреннее состояние объекта без нарушения принципа инкапсуляции.
  • Гибкое управление историческими состояниями объекта, что удобно для выполнения операций отмены и повтора.
  • Возможность внешнего сохранения состояния, избегая раскрытия внутреннего состояния объекта.

3. Примеры практических применений паттерна Memento

Паттерн Memento имеет множество практических сценариев применения, некоторые из которых включают:

  • Функциональность отмены и повтора в текстовых редакторах, которая может использовать паттерн Memento для сохранения состояния каждой операции.
  • Функциональность сохранения и загрузки в играх, которая может использовать паттерн Memento для сохранения прогресса игры.
  • Возможность сохранения черновиков в почтовых клиентах, которая может использовать паттерн Memento для сохранения состояния черновых писем.

4. Реализация паттерна Memento в Golang

4.1. Диаграмма классов UML

Паттерн Memento в Golang

4.2. Введение в пример

Описание на основе диаграммы классов UML

В этом примере у нас есть класс Originator с внутренним состоянием, называемым "state". Originator устанавливает состояние с использованием метода SetState и создает объект memento с помощью метода CreateMemento. Внутреннее состояние объекта memento такое же, как у Originator. Класс Caretaker отвечает за сохранение объекта memento и добавление memento с помощью метода AddMemento.

Шаги реализации

  1. Создайте объект Memento, у которого есть метод GetState для сохранения внутреннего состояния Originator.
  2. Создайте объект Originator, у которого есть методы для установки состояния и создания memento.
  3. Создайте объект Caretaker, который отвечает за сохранение объекта memento.
  4. Реализуйте методы для создания memento и восстановления состояния в Originator:
    • При создании объекта memento сохраните состояние Originator в memento.
    • При восстановлении состояния восстановите состояние из memento в Originator.
  5. Реализуйте методы для добавления memento и получения memento в Caretaker:
    • Метод добавления memento используется для сохранения объекта memento в Caretaker.
    • Метод получения memento используется для извлечения объекта memento из Caretaker.

4.3.1. Создание объекта Memento

type Memento struct {
	state string
}

func (m *Memento) GetState() string {
	return m.state
}

4.3.2. Сохранение состояния в Memento

type Originator struct {
	state string
}

func (o *Originator) SetState(state string) {
	o.state = state
}

func (o *Originator) CreateMemento() *Memento {
	return &Memento{state: o.state}
}

4.3.3. Восстановление состояния из Memento

func (o *Originator) SetMemento(memento *Memento) {
	o.state = memento.GetState()
}

4.3.4. Использование паттерна Memento для операций отмены

type Caretaker struct {
	mementos []*Memento
}

func (c *Caretaker) AddMemento(m *Memento) {
	c.mementos = append(c.mementos, m)
}

func (c *Caretaker) GetMemento(index int) *Memento {
	return c.mementos[index]
}
func main() {
	originator := &Originator{}
	caretaker := &Caretaker{}

	originator.SetState("State 1")
	caretaker.AddMemento(originator.CreateMemento())

	originator.SetState("State 2")
	caretaker.AddMemento(originator.CreateMemento())

	originator.SetMemento(caretaker.GetMemento(0))
	fmt.Println("Состояние Originator после восстановления до состояния 1:", originator.state)

	originator.SetMemento(caretaker.GetMemento(1))
	fmt.Println("Состояние Originator после восстановления до состояния 2:", originator.state)
}