1. Co to jest wzorzec Memento

Wzorzec Memento to behawioralny wzorzec projektowy używany do zapisywania i przywracania wewnętrznego stanu obiektu. Zapisuje stan obiektu do obiektu memento, który może być użyty do przywrócenia obiektu do poprzedniego stanu w przyszłości.

2. Charakterystyka i Zalety wzorca Memento

Charakterystyka i zalety wzorca Memento obejmują:

  • Może zapisać i przywrócić wewnętrzny stan obiektu bez naruszania zasady enkapsulacji.
  • Może elastycznie zarządzać historycznymi stanami obiektu, ułatwiając wykonywanie operacji cofania i ponawiania.
  • Pozwala na zapis stanu na zewnątrz, unikając ujawnienia wewnętrznego stanu obiektu.

3. Przykłady praktycznych zastosowań wzorca Memento

Wzorzec Memento posiada wiele praktycznych scenariuszy zastosowań, przykłady obejmują:

  • Funkcja cofania i ponawiania w edytorach tekstowych, które mogą używać wzorca Memento do zapisywania stanu każdej operacji.
  • Funkcja zapisywania i ładowania w grach, które mogą używać wzorca Memento do zapisywania postępu gry.
  • Funkcja przechowywania szkiców w klientach poczty e-mail, które mogą używać wzorca Memento do zapisywania stanu szkiców e-maili.

4. Implementacja wzorca Memento w języku Golang

4.1. Diagram UML Klasy

Wzorzec Memento w języku Golang

4.2. Wprowadzenie do przykładu

Opis na podstawie diagramu UML Klasy

W tym przykładzie mamy klasę Originator z wewnętrznym stanem o nazwie "state". Originator ustawia stan za pomocą metody SetState i tworzy obiekt memento za pomocą metody CreateMemento. Wewnętrzny stan obiektu memento jest taki sam jak w przypadku Originator. Klasa Caretaker jest odpowiedzialna za przechowywanie obiektu memento i dodawanie memento za pomocą metody AddMemento.

Kroki implementacji

  1. Utwórz obiekt Memento, który ma metodę GetState do zapisania wewnętrznego stanu Originatora.
  2. Utwórz obiekt Originator, który ma metody do ustawiania stanu i tworzenia memento.
  3. Utwórz obiekt Caretaker, który jest odpowiedzialny za zapisywanie obiektu memento.
  4. Zaimplementuj metody do tworzenia memento i przywracania stanu w Originatorze:
    • Przy tworzeniu obiektu memento zapisz stan Originatora w memento.
    • Przy przywracaniu stanu przywróć stan z memento do Originatora.
  5. Zaimplementuj metody do dodawania memento i pobierania memento w Caretakerze:
    • Metoda dodawania memento służy do zapisywania obiektu memento w Caretakerze.
    • Metoda pobierania memento służy do pobrania obiektu memento z Caretakera.

4.3.1. Utwórz obiekt Memento

type Memento struct {
	state string
}

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

4.3.2. Zapisz stan w obiekcie 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. Przywróć stan z obiektu Memento

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

4.3.4. Użycie wzorca Memento do operacji cofania

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]
}

4.3.5. Korzystanie z wzorca Memento do operacji powtórzenia

func main() {
	originator := &Originator{}
	caretaker := &Caretaker{}

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

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

	originator.SetMemento(caretaker.GetMemento(0))
	fmt.Println("Stan oryginalny po przywróceniu do stanu 1:", originator.state)

	originator.SetMemento(caretaker.GetMemento(1))
	fmt.Println("Stan oryginalny po przywróceniu do stanu 2:", originator.state)
}