Memento-ontwerppatroon in Java

1. Overzicht

In deze tutorial leren we wat het Memento Design Pattern is en hoe je het kunt gebruiken.

Eerst gaan we wat theorie doornemen. Vervolgens maken we een voorbeeld waarin we het gebruik van het patroon zullen illustreren.

2. Wat is het ontwerppatroon van Memento?

Het Memento Design Pattern, beschreven door de Gang of Four in hun boek, is een gedragsontwerppatroon. Het Memento Design Pattern biedt een oplossing om onneembare acties te implementeren. We kunnen dit doen door de staat van een object op een bepaald moment op te slaan en deze te herstellen als de sindsdien uitgevoerde acties ongedaan moeten worden gemaakt.

In de praktijk wordt het object waarvan de staat moet worden opgeslagen een Originator genoemd. De verzorger is het object dat het opslaan en herstellen van de staat activeert, die het aandenken wordt genoemd.

Het Memento-object moet zo min mogelijk informatie aan de verzorger blootstellen. Dit is om ervoor te zorgen dat we de interne toestand van de Originator niet aan de buitenwereld blootstellen, aangezien dit de inkapselingsprincipes zou breken. De vinder moet echter toegang hebben tot voldoende informatie om de oorspronkelijke staat te herstellen.

Laten we een snel klassendiagram bekijken dat illustreert hoe de verschillende objecten met elkaar omgaan:

Zoals we kunnen zien, kan de vinder een aandenken produceren en consumeren. Ondertussen behoudt de Caretaker alleen de staat voordat hij deze herstelt. De interne representatie van de Originator wordt verborgen gehouden voor de buitenwereld.

Hier hebben we echter een enkel veld gebruikt om de staat van de Originator weer te geven we zijn niet beperkt tot één veld en hadden zoveel velden kunnen gebruiken als nodig was. Bovendien hoeft de status in het Memento-object niet overeen te komen met de volledige status van de Originator. Zolang de bewaarde informatie voldoende is om de staat van de Originator te herstellen, zijn we klaar om te gaan.

3. Wanneer moet u een Memento-ontwerppatroon gebruiken?

Doorgaans wordt het Memento-ontwerppatroon gebruikt in situaties waarin sommige acties ongedaan kunnen worden gemaakt en daarom moet worden teruggedraaid naar een vorige staat. Als de staat van de Originator echter zwaar is, kan het gebruik van het Memento Design Pattern leiden tot een duur creatieproces en een verhoogd geheugengebruik.

4. Voorbeeld van het aandenkenpatroon

4.1. Eerste monster

Laten we nu een voorbeeld bekijken van het Memento-ontwerppatroon. Laten we ons voorstellen dat we een teksteditor hebben:

openbare klasse TextEditor {privé TextWindow textWindow; openbare TextEditor (TextWindow textWindow) {this.textWindow = textWindow; }}

Het heeft een tekstvenster dat de momenteel ingevoerde tekst bevat en biedt een manier om meer tekst toe te voegen:

openbare klasse TextWindow {privé StringBuilder currentText; openbare TextWindow () {this.currentText = nieuwe StringBuilder (); } public void addText (String-tekst) {currentText.append (tekst); }}

4.2. Memento

Laten we ons nu eens voorstellen dat we willen dat onze teksteditor enkele functies voor opslaan en ongedaan maken implementeert. Bij het opslaan willen we dat onze huidige tekst wordt opgeslagen. Dus als we latere wijzigingen ongedaan maken, zullen we onze opgeslagen tekst herstellen.

Om dat te doen, maken we gebruik van het Memento Design Pattern. Eerst maken we een object met de huidige tekst van het venster:

openbare klasse TextWindowState {privé String-tekst; openbare TextWindowState (String-tekst) {this.text = text; } public String getText () {retourtekst; }}

Dit object is ons aandenken. Zoals we kunnen zien, kiezen we ervoor om te gebruiken Draad in plaats van StringBuilder om te voorkomen dat de huidige tekst door buitenstaanders wordt bijgewerkt.

4.3. Vinder

Daarna moeten we het TextWindow klasse met methoden om het Memento-object te maken en te consumeren, waardoor de TextWindow onze vinder:

openbare TextWindowState save () {retourneer nieuwe TextWindowState (wholeText.toString ()); } openbare ongeldige herstel (TextWindowState opslaan) {currentText = nieuwe StringBuilder (save.getText ()); }

De sparen() methode stelt ons in staat om het object te maken, terwijl de herstellen() methode gebruikt het om de vorige staat te herstellen.

4.4. Verzorger

Ten slotte moeten we onze Teksteditor klasse. Als verzorger zal het de staat van de initiator behouden en vragen om het te herstellen wanneer dat nodig is:

privé TextWindowState opgeslagenTextWindow; openbare leegte hitSave () {savedTextWindow = textWindow.save (); } openbare ongeldige hitUndo () {textWindow.restore (opgeslagenTextWindow); }

4.5. De oplossing testen

Laten we kijken of het werkt door middel van een proefrit. Stel je voor dat we wat tekst aan onze editor toevoegen, deze opslaan, dan nog wat toevoegen en ten slotte ongedaan maken. Om dat te bereiken, voegen we een afdrukken() methode op onze Teksteditor dat geeft een Draad van de huidige tekst:

TextEditor textEditor = new TextEditor (new TextWindow ()); textEditor.write ("The Memento Design Pattern \ n"); textEditor.write ("Hoe implementeer ik het in Java? \ n"); textEditor.hitSave (); textEditor.write ("Koop melk en eieren voordat je naar huis komt \ n"); textEditor.hitUndo (); assertThat (textEditor.print ()). isEqualTo ("Het Memento-ontwerppatroon \ nHoe het in Java te implementeren? \ n");

Zoals we kunnen zien, maakt de laatste zin geen deel uit van de huidige tekst, omdat het aandenken is opgeslagen voordat het werd toegevoegd.

5. Conclusie

In dit korte artikel hebben we het Memento-ontwerppatroon uitgelegd en waarvoor het kan worden gebruikt. We hebben ook een voorbeeld doorgenomen dat het gebruik ervan in een eenvoudige teksteditor illustreert.

De volledige code die in dit artikel wordt gebruikt, is te vinden op GitHub.