Java-Entwurfsmuster (design pattern): Memento

Heute werfen wir einen Blick auf das nächste Entwurfsmuster (Java design patterns) aus der Kategorie der Verhaltensmuster (Behavioral Patterns) – Memento. Entwurfsmuster in dieser Kategorie befassen sich mit der Kommunikation(interaction) zwischen Objekten und ihrer Verantwortung (responsibility).

Was ist das Memento Entwurfsmuster?

Das Entwurfsmuster Memento ermöglicht es, den internen Zustand des Objekts zu erhalten, ohne dasKapselungsprinzip zu verletzen. Dieser Zustand kann bei Bedarf wiederhergestellt werden, wodurch das Objekt in seinen ursprünglichen Zustand zurückkehrt.

Was für ein Problem löst das Entwurfsmuster Memento?

In Anwendungen ist es durchaus üblich, den Status zu speichern, den der Benutzer als Eingabe in das Programm eingegeben hat, z.B. beim Ausfüllen eines Webformulars. Im Falle eines Internetausfalls ist es sinnvoll, den zuletzt gespeicherten Zustand der eingegebenen Daten wiederherzustellen, ohne den Benutzer erneut danach zu fragen. In ähnlichen Situationen, in denen wir den Zwischenzustand speichern und jederzeit leicht darauf zurückgreifen müssen, wird das Entwurfsmuster Memento verwendet. Das Prinzip besteht darin, die Speicherung des Zustands eines Objekts vom eigentlichen Objekt zu trennen. Ein Objekt, das seinen Zustand speichern möchte, erstellt ein Memento-Objekt, das die erforderlichen Informationen über den Zustand enthält. Dieses Memento-Objekt kann dann gespeichert werden (zum Beispiel in einer Historie) und später verwendet werden, um den ursprünglichen Zustand des Objekts wiederherzustellen. Ein gut konzipiertes Objekt ist gekapselt, d. h. die Daten des Objekts sind im Inneren verborgen und von außerhalb des Objekts nicht zugänglich, so dass das Objekt selbst – der Originator – für die Speicherung des internen Zustands im (Memento)-Objekt und dessen Wiederherstellung aus dem (Memento)-Objekt verantwortlich ist. Der Client (Caretaker) übernimmt im Fall der Speicherung des Zustands das Memento-Objekt vom Originator-Objekt und gibt es ihm später zurück, wenn der Zustand wiederhergestellt werden soll. Diese Methode ermöglicht es, den internen Zustand des Originator-Objekts zu speichern und wiederherzustellen, ohne seine Kapselung aufzubrechen.

Ein Beispiel für eine Memento-Implementierung in Java.

Um das Memento-Entwurfsmuster zu demonstrieren, zeigen wir, wie man den Zustand eines Objekts speichert und wiederherstellt, ohne das Prinzip der Kapselung zu verletzen. Dazu erstellen wir ein einfaches Spiel, in dem der Spieler durch gefährliche Levels geht, in denen er Verletzungen erleiden kann. Der Spieler kann jederzeit den Spielzustand speichern und ihn bei Bedarf wiederherstellen. Hra.java

package designpatterns;

public class Hra {
    private int levelId;
    private int zdravie;

    public Hra() {
        spustitHru();
    }

    public void spustitHru() {
        this.levelId = 1;
        this.zdravie = 100;
        System.out.println("Spúšťam novú hru.");
        ukazStavHry();
    }

    public Memento ulozitHru() {
        System.out.println("Ukladám stav hry.");
        return new Memento(levelId, zdravie);
    }

    public void nacitatHru(Memento memento) {
        System.out.println("Načítavam uloženú pozíciu v hre.");
        this.levelId = memento.getLevelId();
        this.zdravie = memento.getZdravie();
    }

    public void dokoncitLevel() {
        levelId++;
        System.out.println("Pokračujem do levelu " + levelId);
        ukazStavHry();
    }

    public void zranitSa(int poskodenie) {
        this.zdravie -= poskodenie;
        System.out.println("Hráč utrpel zranenie (" + -poskodenie + ")");
        ukazStavHry();
        if (zdravie <= 0) {
            System.out.println("Hráč stratil celé zdravie. Hra začne od začiatku.");
            spustitHru();
        }
    }

    public void ukazStavHry() {
        System.out.println("    Level " + levelId + ", Zdravie: " + zdravie);
    }
}

Die Klasse Hra enthält Methoden zum Starten eines Spiels, Speichern eines Spiels, Laden eines Spiels, Abschließen eines Levels, Verletzen eines Spielers und Anzeigen des Spielstatus. Memento.java

package designpatterns;

public class Memento {
    private int levelId;
    private int zdravie;

    public Memento(int levelId, int zdravie) {
        this.levelId = levelId;
        this.zdravie = zdravie;
    }

    public int getLevelId() {
        return levelId;
    }

    public int getZdravie() {
        return zdravie;
    }
}

Die Klasse Memento dient als Objekt, das den Zustand des Spiels speichert. Das Memento speichert Informationen über den aktuellen Level (levelId) und die Gesundheit (zdravie). Hranie.java

import designpatterns.Hra;
import designpatterns.Memento;

public class Hranie {
    public static void main(String[] args) {
        Hra hra = new Hra();
        hra.zranitSa(12);
        hra.dokoncitLevel();
        Memento ulozenaPozicia = hra.ulozitHru();
        hra.zranitSa(24);
        hra.zranitSa(18);
        hra.dokoncitLevel();
        hra.zranitSa(20);
        hra.zranitSa(12);
        hra.zranitSa(14);
        hra.nacitatHru(ulozenaPozicia);
        hra.ukazStavHry();
    }
}

Die Klasse Hranie enthält die Methode main, in der die Verwendung des Memento-Entwurfsmusters demonstriert wird. Der Spieler startet das Spiel, erleidet Verletzungen, schließt ein Level ab, speichert den Spielzustand (Memento), erleidet weitere Verletzungen, schließt ein weiteres Level ab, erleidet erneut Verletzungen und lädt schließlich den Spielstand, um nicht von vorne beginnen zu müssen. Die Ausgabe dieses Beispiels ist: Beispiel für die Ausgabe des Entwurfsmusters Memento.

Zusammenfassung

Das Memento ist ein Entwurfsmuster, das das Problem der Speicherung und Wiederherstellung des Zustands eines Objekts löst, so dass es zu einem früheren Zustand zurückkehren kann. Sie wird häufig verwendet, um einen Undo/Rollback-Mechanismus zu implementieren oder um eine Historie der Objektzustände zu führen. Wir haben die Dateien mit dem obigen Beispiel in Form von Code vorbereitet, den du direkt in Java ausführen kannst. Lade den Code Java Memento hier herunter. Wenn du als Java-Programmierer auf der Suche nach Arbeit bist, schau dir unsere Mitarbeiterbenefits an und reagiere auf unsere aktuellen Stellenausschreibungen.

Über den Autor

Jozef Wagner

Java Developer Senior

Viac ako 10 rokov programujem v Jave, momentálne pracujem v msg life Slovakia ako Java programátor senior a pomáham zákazníkom implementovať ich požiadavky do poistného softvéru Life Factory. Vo voľnom čase si rád oddýchnem v lese, prípadne si zahrám nejakú dobrú počítačovú hru.

Informieren Sie uns über sich