1. Was ist das Memento-Muster

Das Memento-Muster ist ein Verhaltensmuster, das verwendet wird, um den internen Zustand eines Objekts zu speichern und wiederherzustellen. Es speichert den Zustand eines Objekts in einem Memento-Objekt, das in Zukunft verwendet werden kann, um das Objekt auf einen früheren Zustand zurückzusetzen.

2. Merkmale und Vorteile des Memento-Musters

Die Merkmale und Vorteile des Memento-Musters umfassen:

  • Es kann den internen Zustand eines Objekts speichern und wiederherstellen, ohne das Prinzip der Kapselung zu verletzen.
  • Es kann historische Zustände eines Objekts flexibel verwalten, um das Durchführen von Rückgängig- und Wiederherstellungsvorgängen zu vereinfachen.
  • Es ermöglicht die externe Speicherung des Zustands und vermeidet dadurch die Bloßstellung des internen Zustands des Objekts.

3. Beispiele für praktische Anwendungen des Memento-Musters

Das Memento-Muster hat viele praktische Anwendungsszenarien, zu denen einige Beispiele gehören:

  • Die Rückgängig- und Wiederholungsfunktion in Texteditoren, die das Memento-Muster verwenden können, um den Zustand jeder Operation zu speichern.
  • Die Speicher- und Lade-Funktionen in Spielen, die das Memento-Muster verwenden können, um den Spielverlauf zu speichern.
  • Die Entwurfspeicherfunktion in E-Mail-Clients, die das Memento-Muster verwenden können, um den Zustand von Entwurfs-E-Mails zu speichern.

4. Implementierung des Memento-Musters in Golang

4.1. UML-Klassendiagramm

Memento-Muster in Golang

4.2. Beispiel-Einführung

Beschreibung basierend auf dem UML-Klassendiagramm

In diesem Beispiel haben wir eine Originator-Klasse mit einem internen Zustand namens "state". Der Originator setzt den Zustand mit der Methode SetState und erstellt ein Memento-Objekt mit der Methode CreateMemento. Der interne Zustand des Memento-Objekts ist der gleiche wie der des Originators. Die Caretaker-Klasse ist verantwortlich für die Speicherung des Memento-Objekts und das Hinzufügen von Momenten mit der Methode AddMemento.

Implementierungsschritte

  1. Erstellen Sie das Memento-Objekt, das eine Methode GetState zum Speichern des internen Zustands des Originators hat.
  2. Erstellen Sie das Originator-Objekt, das Methoden zum Setzen des Zustands und zum Erstellen eines Mementos hat.
  3. Erstellen Sie das Caretaker-Objekt, das für das Speichern des Memento-Objekts verantwortlich ist.
  4. Implementieren Sie die Methoden zum Erstellen eines Mementos und zum Wiederherstellen des Zustands im Originator:
    • Beim Erstellen eines Memento-Objekts den Zustand des Originators im Memento speichern.
    • Beim Wiederherstellen des Zustands den Zustand aus dem Memento im Originator wiederherstellen.
  5. Implementieren Sie die Methoden zum Hinzufügen eines Mementos und zum Abrufen eines Mementos im Caretaker:
    • Die Methode zum Hinzufügen eines Mementos wird verwendet, um das Memento-Objekt im Caretaker zu speichern.
    • Die Methode zum Abrufen eines Mementos wird verwendet, um das Memento-Objekt aus dem Caretaker abzurufen.

4.3.1. Erstellen eines Memento-Objekts

type Memento struct {
	state string
}

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

4.3.2. Zustand im Memento speichern

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. Zustand aus dem Memento wiederherstellen

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

4.3.4. Verwendung des Memento-Musters für Rückgängig-Operationen

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. Verwenden des Memento-Musters für Redo-Operationen

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

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

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

	originator.SetMemento(caretaker.GetMemento(0))
	fmt.Println("Zustand des Originators nach der Wiederherstellung von Zustand 1:", originator.state)

	originator.SetMemento(caretaker.GetMemento(1))
	fmt.Println("Zustand des Originators nach der Wiederherstellung von Zustand 2:", originator.state)
}