Uzorak dizajna Memento u Javi

1. Pregled

U ovom uputstvu naučit ćemo što je Memento Design Pattern i kako ga koristiti.

Prvo ćemo proći kroz malo teorije. Zatim ćemo stvoriti primjer gdje ćemo ilustrirati upotrebu uzorka.

2. Što je obrazac dizajna Memento?

Uzorak dizajna Memento, koji je Gang of Four opisao u svojoj knjizi, obrazac je dizajna ponašanja. Uzorak dizajna Memento nudi rješenje za provođenje neizvedivih radnji. To možemo učiniti spremanjem stanja objekta u određenom trenutku i vraćanjem ako radnje koje su izvršene moraju biti poništene.

Praktično se objekt čije stanje treba spasiti naziva Originator. Domar je objekt koji pokreće spašavanje i obnavljanje stanja, a koji se naziva Memento.

Predmet Memento trebao bi Domu izložiti što manje podataka. Time se osigurava da unutarnje stanje Izvornika ne izlažemo vanjskom svijetu, jer bi to kršilo principe inkapsulacije. Međutim, izvornik bi trebao pristupiti dovoljno informacija kako bi se vratio u izvorno stanje.

Pogledajmo brzi dijagram klasa koji ilustrira kako različiti objekti međusobno djeluju:

Kao što vidimo, Originator može proizvesti i konzumirati Memento. U međuvremenu, Domar samo zadržava državu prije nego što je obnavlja. Unutarnji prikaz Izvornika skriven je od vanjskog svijeta.

Ovdje smo, međutim, koristili jedno polje za predstavljanje države Izvornika nismo ograničeni na jedno polje i mogli smo upotrijebiti onoliko polja koliko je potrebno. Osim toga, stanje u objektu Memento ne mora se podudarati sa punim stanjem Izvornika. Sve dok su zadržane informacije dovoljne za vraćanje stanja Izvornika, spremni smo za početak.

3. Kada koristiti obrazac dizajna Memento?

Uobičajeno, obrazac dizajna Memento upotrebljavat će se u situacijama kada se neke radnje ne mogu izvršiti, pa se zahtijeva vraćanje u prethodno stanje. Međutim, ako je stanje Originatora teško, upotreba uzorka dizajna Memento može dovesti do skupog postupka stvaranja i povećane upotrebe memorije.

4. Primjer uzorka za uspomenu

4.1. Početni uzorak

Pogledajmo sada primjer uzorka dizajna Memento. Zamislimo da imamo uređivač teksta:

javna klasa TextEditor {private TextWindow textWindow; javni TextEditor (TextWindow textWindow) {this.textWindow = textWindow; }}

Ima tekstualni prozor u kojem se nalazi trenutno uneseni tekst i pruža način za dodavanje još teksta:

javna klasa TextWindow {private StringBuilder currentText; javni TextWindow () {this.currentText = novi StringBuilder (); } public void addText (tekst niza) {currentText.append (text); }}

4.2. Uspomena

Zamislimo sada da želimo da naš uređivač teksta implementira neke značajke spremanja i poništavanja. Prilikom spremanja želimo da se sačuva naš trenutni tekst. Stoga ćemo prilikom poništavanja naknadnih promjena obnoviti naš spremljeni tekst.

Da bismo to učinili, poslužit ćemo se uzorkom dizajna Memento. Prvo ćemo stvoriti objekt koji sadrži trenutni tekst prozora:

javna klasa TextWindowState {privatni tekst niza; javni TextWindowState (tekst u nizu) {this.text = text; } javni String getText () {return tekst; }}

Ovaj objekt je naš Memento. Kao što vidimo, odlučili smo se koristiti Niz umjesto StringBuilder kako bi spriječili bilo kakvo ažuriranje trenutnog teksta od strane stranaca.

4.3. Izvornik

Nakon toga morat ćemo pružiti TextWindow klase s metodama za stvaranje i konzumiranje objekta Memento, čineći TextWindow naš začetnik:

public TextWindowState save () {return new TextWindowState (wholeText.toString ()); } javno vraćanje praznine (spremanje TextWindowState) {currentText = novi StringBuilder (save.getText ()); }

The uštedjeti() metoda omogućuje nam stvaranje objekta, dok vratiti() metoda ga troši za vraćanje prethodnog stanja.

4.4. Domar

Napokon, moramo ažurirati svoj Uređivač teksta razred. Kao domar, on će držati državu začetnika i tražiti da se obnovi po potrebi:

private TextWindowState savedTextWindow; javna praznina hitSave () {savedTextWindow = textWindow.save (); } javna void hitUndo () {textWindow.restore (savedTextWindow); }

4.5. Testiranje rješenja

Pogledajmo funkcionira li kroz uzorak. Zamislite da u naš uređivač dodamo malo teksta, spremimo ga, a zatim dodamo još i na kraju poništimo. Da bismo to postigli, dodati ćemo a ispis () metoda na našem Uređivač teksta koji vraća a Niz trenutnog teksta:

TextEditor textEditor = novi TextEditor (novi TextWindow ()); textEditor.write ("Uzorak dizajna Memento \ n"); textEditor.write ("Kako to implementirati u Javi? \ n"); textEditor.hitSave (); textEditor.write ("Kupite mlijeko i jaja prije povratka kući \ n"); textEditor.hitUndo (); assertThat (textEditor.print ()). isEqualTo ("Uzorak dizajna Memento \ nKako ga implementirati u Javi? \ n");

Kao što vidimo, posljednja rečenica nije dio trenutnog teksta, jer je Memento spremljen prije dodavanja.

5. Zaključak

U ovom kratkom članku objasnili smo obrazac dizajna Memento i za što se on može koristiti. Također smo prošli kroz primjer koji ilustrira njegovu upotrebu u jednostavnom uređivaču teksta.

Cjelokupni kod korišten u ovom članku možete pronaći na GitHubu.