1. Co to jest wzorzec Memento
Wzorzec Memento to behawioralny wzorzec projektowy używany do zapisywania i przywracania wewnętrznego stanu obiektu. Zapisuje stan obiektu do obiektu memento, który może być użyty do przywrócenia obiektu do poprzedniego stanu w przyszłości.
2. Charakterystyka i Zalety wzorca Memento
Charakterystyka i zalety wzorca Memento obejmują:
- Może zapisać i przywrócić wewnętrzny stan obiektu bez naruszania zasady enkapsulacji.
- Może elastycznie zarządzać historycznymi stanami obiektu, ułatwiając wykonywanie operacji cofania i ponawiania.
- Pozwala na zapis stanu na zewnątrz, unikając ujawnienia wewnętrznego stanu obiektu.
3. Przykłady praktycznych zastosowań wzorca Memento
Wzorzec Memento posiada wiele praktycznych scenariuszy zastosowań, przykłady obejmują:
- Funkcja cofania i ponawiania w edytorach tekstowych, które mogą używać wzorca Memento do zapisywania stanu każdej operacji.
- Funkcja zapisywania i ładowania w grach, które mogą używać wzorca Memento do zapisywania postępu gry.
- Funkcja przechowywania szkiców w klientach poczty e-mail, które mogą używać wzorca Memento do zapisywania stanu szkiców e-maili.
4. Implementacja wzorca Memento w języku Golang
4.1. Diagram UML Klasy
4.2. Wprowadzenie do przykładu
Opis na podstawie diagramu UML Klasy
W tym przykładzie mamy klasę Originator z wewnętrznym stanem o nazwie "state". Originator ustawia stan za pomocą metody SetState i tworzy obiekt memento za pomocą metody CreateMemento. Wewnętrzny stan obiektu memento jest taki sam jak w przypadku Originator. Klasa Caretaker jest odpowiedzialna za przechowywanie obiektu memento i dodawanie memento za pomocą metody AddMemento.
Kroki implementacji
- Utwórz obiekt Memento, który ma metodę GetState do zapisania wewnętrznego stanu Originatora.
- Utwórz obiekt Originator, który ma metody do ustawiania stanu i tworzenia memento.
- Utwórz obiekt Caretaker, który jest odpowiedzialny za zapisywanie obiektu memento.
- Zaimplementuj metody do tworzenia memento i przywracania stanu w Originatorze:
- Przy tworzeniu obiektu memento zapisz stan Originatora w memento.
- Przy przywracaniu stanu przywróć stan z memento do Originatora.
- Zaimplementuj metody do dodawania memento i pobierania memento w Caretakerze:
- Metoda dodawania memento służy do zapisywania obiektu memento w Caretakerze.
- Metoda pobierania memento służy do pobrania obiektu memento z Caretakera.
4.3.1. Utwórz obiekt Memento
type Memento struct {
state string
}
func (m *Memento) GetState() string {
return m.state
}
4.3.2. Zapisz stan w obiekcie Memento
type Originator struct {
state string
}
func (o *Originator) SetState(state string) {
o.state = state
}
func (o *Originator) CreateMemento() *Memento {
return &Memento{state: o.state}
}
4.3.3. Przywróć stan z obiektu Memento
func (o *Originator) SetMemento(memento *Memento) {
o.state = memento.GetState()
}
4.3.4. Użycie wzorca Memento do operacji cofania
type Caretaker struct {
mementos []*Memento
}
func (c *Caretaker) AddMemento(m *Memento) {
c.mementos = append(c.mementos, m)
}
func (c *Caretaker) GetMemento(index int) *Memento {
return c.mementos[index]
}
4.3.5. Korzystanie z wzorca Memento do operacji powtórzenia
func main() {
originator := &Originator{}
caretaker := &Caretaker{}
originator.SetState("Stan 1")
caretaker.AddMemento(originator.CreateMemento())
originator.SetState("Stan 2")
caretaker.AddMemento(originator.CreateMemento())
originator.SetMemento(caretaker.GetMemento(0))
fmt.Println("Stan oryginalny po przywróceniu do stanu 1:", originator.state)
originator.SetMemento(caretaker.GetMemento(1))
fmt.Println("Stan oryginalny po przywróceniu do stanu 2:", originator.state)
}