Memento design mønster i Java

1. Oversigt

I denne vejledning lærer vi, hvad Memento Design Pattern er, og hvordan man bruger det.

Først gennemgår vi en smule teori. Derefter opretter vi et eksempel, hvor vi illustrerer brugen af ​​mønsteret.

2. Hvad er Memento-designmønsteret?

Memento Design Pattern, der er beskrevet af Gang of Four i deres bog, er et adfærdsmæssigt designmønster. Memento-designmønsteret tilbyder en løsning til implementering af fortrydelige handlinger. Vi kan gøre dette ved at gemme et objekts tilstand på et givet øjeblik og gendanne det, hvis de handlinger, der er udført siden, skal fortrydes.

Praktisk kaldes objektet, hvis tilstand skal gemmes, en Originator. Vagter er objektet, der udløser redning og gendannelse af staten, der kaldes Memento.

Memento-objektet skal udsætte så lidt information som muligt for vicevært. Dette er for at sikre, at vi ikke udsætter Originatorens interne tilstand for omverdenen, da det ville bryde indkapslingsprincipperne. Oprinderen skal dog have adgang til tilstrækkelig information for at gendanne til den oprindelige tilstand.

Lad os se et hurtigt klassediagram, der illustrerer, hvordan de forskellige objekter interagerer med hinanden:

Som vi kan se, kan originatoren producere og forbruge et minde. I mellemtiden holder vicevagteren kun staten, før den genopretter den. Originatorens interne repræsentation holdes skjult for den ydre verden.

Her brugte vi dog et enkelt felt til at repræsentere tilstanden til ophavsmanden vi er ikke begrænset til et felt og kunne have brugt så mange felter som nødvendigt. Plus, at staten, der er indeholdt i Memento-objektet, ikke behøver at matche den oprindelige fulde tilstand. Så længe de gemte oplysninger er tilstrækkelige til at gendanne opretterens tilstand, er vi klar til at gå.

3. Hvornår skal man bruge Memento Design Pattern?

Typisk vil Memento-designmønsteret blive brugt i situationer, hvor nogle handlinger kan fortrydes, og derfor kræver tilbagevenden til en tidligere tilstand. Men hvis tilstanden til originatoren er tung, kan brug af Memento Design Pattern føre til en dyr oprettelsesproces og øget brug af hukommelse.

4. Eksempel på mindemønsteret

4.1. Indledende prøve

Lad os nu se et eksempel på Memento Design Pattern. Lad os forestille os, at vi har en teksteditor:

offentlig klasse TextEditor {privat TextWindow textWindow; public TextEditor (TextWindow textWindow) {this.textWindow = textWindow; }}

Det har et tekstvindue, der indeholder den aktuelt indtastede tekst og giver en måde at tilføje mere tekst på:

offentlig klasse TextWindow {private StringBuilder currentText; offentlig TextWindow () {this.currentText = ny StringBuilder (); } public void addText (String text) {currentText.append (text); }}

4.2. Memento

Lad os forestille os, at vi vil have vores teksteditor til at implementere nogle gemme- og fortrydelsesfunktioner. Når du gemmer, ønsker vi, at vores nuværende tekst gemmes. Når vi fortryder efterfølgende ændringer, får vi derfor vores gemte tekst gendannet.

For at gøre det, bruger vi Memento Design Pattern. Først opretter vi et objekt, der indeholder den aktuelle tekst i vinduet:

offentlig klasse TextWindowState {privat strengtekst; offentlig TextWindowState (strengtekst) {this.text = tekst; } offentlig String getText () {returtekst; }}

Dette objekt er vores Memento. Som vi kan se, vælger vi at bruge Snor i stedet for StringBuilder for at forhindre enhver opdatering af den aktuelle tekst af udenforstående.

4.3. Opretter

Derefter bliver vi nødt til at give TextWindow klasse med metoder til at oprette og forbruge Memento-objektet, hvilket gør TextWindow vores ophavsmand:

offentlig TextWindowState gem () {returner ny TextWindowState (heltekst.toString ()); } offentlig ugyldig gendannelse (TextWindowState gem) {currentText = ny StringBuilder (gem.getText ()); }

Det Gemme() metode giver os mulighed for at oprette objektet, mens gendan () metode forbruger den for at gendanne den tidligere tilstand.

4.4. Vicevært

Endelig er vi nødt til at opdatere vores TextEditor klasse. Som vicevært holder den oprindelsesstatus og beder om at gendanne den, når det er nødvendigt:

privat TextWindowState gemtTextWindow; offentlig ugyldighed hitSave () {savedTextWindow = textWindow.save (); } offentligt ugyldigt hitUndo () {textWindow.restore (savedTextWindow); }

4.5. Test af løsningen

Lad os se, om det fungerer gennem en prøvekørsel. Forestil dig, at vi tilføjer noget tekst til vores editor, gemmer det, tilføjer derefter mere og til sidst fortryder. For at opnå dette tilføjer vi en Print() metode på vores TextEditor der returnerer en Snor af den aktuelle tekst:

TextEditor textEditor = ny TextEditor (ny TextWindow ()); textEditor.write ("Mønsterets designmønster \ n"); textEditor.write ("Hvordan implementeres det i Java? \ n"); textEditor.hitSave (); textEditor.write ("Køb mælk og æg inden du kommer hjem \ n"); textEditor.hitUndo (); assertThat (textEditor.print ()). isEqualTo ("The Memento Design Pattern \ nHvordan implementerer du det i Java? \ n");

Som vi kan se, er den sidste sætning ikke en del af den aktuelle tekst, da Memento blev gemt, før den blev tilføjet.

5. Konklusion

I denne korte artikel forklarede vi Memento Design Pattern og hvad det kan bruges til. Vi gennemgik også et eksempel, der illustrerer dets anvendelse i en simpel teksteditor.

Den fulde kode, der bruges i denne artikel, kan findes på GitHub.