W swoim aktualnym projekcie, potrzebowałem stworzyć mechanizm umożliwiający cofnięcie zmian wprowadzonych w obrazie. Dzięki wzorcowi Memento można w bardzo łatwy i szybki sposób uzyskać taką funkcjonalność.
Co nam daje Memento?
Pozwala na zachowanie całego stanu obiektu (lub tyle ile potrzebujemy), w celu późniejszego jego odtworzenia, bez naruszenia zasad enkapsulacji.
Spójrzmy na poniższy diagram klas:
Mamy tutaj 3 klasy:
Orginator - jest to obiekt którego stan wewnętrzny chcemy zachować. Poprzez metodę CreateMemennto() tworzy "kopię zapasową" samego siebie a dzięki metodzie SetMemento(Memento) może się odtworzyć z kopi.
Memento - obiekt który jest kopią oryginalnego obiektu. Dzięki metodą GetState() i SetState() pozwalają na odczyt i zapis stanu obiektu.
Caretaker - obiekt ten zarządza obiektami Memento
Przykłady zawsze lepiej działają na wyobraźnię, dlatego spójrzmy na oto taki przykład. Mamy aplikację w której użytkownik wypełnia jakieś pola. Niech to będzie Imię, Nazwisko i wiek. Przyjmijmy, że wygląda ona tak:
Przyjmijmy, że po naciśnięciu przycisku dane zapisują się do bazy danych. Teraz nasz użytkownik wpisuje swoje dane, wciska ok i nagle przypomina mu się że źle wpisał nazwisko. Są dwa wyjścia: wpisze wszystko od początku albo kliknie przycisk cofnij i wpisze poprawne dane. W tym konkretnym przypadku nie wiele będzie kosztowała go pomyłka, jeżeli jednak pól by było więcej to możliwość cofnięcia wprowadzonych danych będzie z pewnością bardzo przydatna. Kod aplikacji:
public class Person
{
private string _firstName;
private string _lastName;
private int _age;
public string FirstName
{
get
{
return _firstName;
}
set
{
_firstName = value;
}
}
public string LastName
{
get
{
return _lastName;
}
set
{
_lastName = value;
}
}
public int Age
{
get
{
return _age;
}
set
{
_age = value;
}
}
/// <summary>
/// Przywraca poprzedni stan obiektu
/// </summary>
/// <param name="memento"></param>
public void SetMemento(Memento memento)
{
this._age = memento.Age;
this._firstName = memento.FirstName;
this._lastName = memento.LastName;
}
/// <summary>
/// Zapisuje aktualny stan obiektu
/// </summary>
/// <returns></returns>
public Memento CreateMemento()
{
return new Memento(_firstName, _lastName, _age);
}
}
public class Memento
{
private string _firstName;
private string _lastName;
private int _age;
public string FirstName
{
get
{
return _firstName;
}
set
{
_firstName = value;
}
}
public string LastName
{
get
{
return _lastName;
}
set
{
_lastName = value;
}
}
public int Age
{
get
{
return _age;
}
set
{
_age = value;
}
}
public Memento(string firstName, string lastName, int age)
{
_firstName = firstName;
_lastName = lastName;
_age = age;
}
}
public class Caretaker
{
private Memento _memento;
public Memento Memento
{
get
{
return _memento;
}
set
{
_memento = value;
}
}
}
Brak komentarzy:
Prześlij komentarz