Wzorzec projektowy pamiątka - memento
Stronę tą wyświetlono już: 2594 razy
Opis wzorca projektowego pamiątka
Wzorzec projektowy pamiątka należy do wzorców czynnościowych. Celem jego jest zaimplementowanie możliwości stworzenia kopii danych przechowywanych w obiekcie lub obiektach klasy. Pamiątka stosowana jest do implementacji cofania i przywracania zmian często spotykanych w programach graficznych czy też tekstowych. Pamiątka może też być swego rodzaju systemem pozwalającym np. zapisywać różne stany gry na dysku twardym, lub przywracać fabryczne ustawienia programu.
Przykładowy diagram UML dla wzorca projektowego pamiątka
Na poniższym diagramie UML klasa Value agreguje klasę Mementos, która zajmuje się wykonywaniem brudnej roboty związanej z obsługą dodawania i usuwania pamiątek a także (częściowo) cofania i przywracania. Klasa Mementos agreguje wielokrotnie Memento. Klasa Value wywołuje odpowiednie metody klasy Mementos przy każdej operacji wpływającej na zmianę stanu obiektu dodając nowy obiekt klasy Memento do klasy Mementos.
Przykładowa implementacja wzorca projektowego pamiątka w C++
- #include <iostream>
- #include <string>
- #include <vector>
- class Memento{
- int state;
- public:
- inline Memento(int value) : state(value){}
- inline int getState() const { return state; }
- };
- class Mementos{
- std::vector<Memento*> mementos;
- int pos;
- public:
- inline Mementos() : pos(-1) {};
- void addMemento(Memento* memento){
- std::cout << "Memento was added!" << std::endl << std::endl;
- if(pos > -1){
- for(std::vector<Memento*>::iterator mem = mementos.begin() + pos + 1; mem < mementos.end(); mem++){
- delete (*mem);
- }
- mementos.erase(mementos.begin() + pos + 1, mementos.end());
- }
- mementos.push_back(memento);
- pos = mementos.size() - 1;
- }
- Memento* redo(){
- if(pos < (int)(mementos.size() - 1)){
- std::cout << std::endl << "Redo action!" << std::endl;
- pos ++;
- return mementos[pos];
- }
- std::cout << std::endl << "You can not redo my old Yedi friend!" << std::endl << std::endl;
- return NULL;
- }
- Memento* undo(){
- if(pos > 0){
- std::cout << std::endl << "Undo action!" << std::endl;
- pos --;
- if(pos > -1)
- return mementos[pos];
- }
- std::cout << std::endl << "You can not undo my old Yedi friend!" << std::endl << std::endl;
- return NULL;
- }
- };
- class Value{
- int value;
- Mementos mementos;
- Memento* getMemento() const { return new Memento(value); }
- public:
- Value(int value) : value(value){
- mementos.addMemento(getMemento());
- }
- void add(){
- int v = 0;
- std::cout<<"Write some value to add: ";
- std::cin>>v;
- std::cout << "Value before add " << value << std::endl;
- value += v;
- std::cout << "Value after add " << value << std::endl << std::endl;
- mementos.addMemento(getMemento());
- }
- void subtract(){
- int v = 0;
- std::cout<<"Write some value to subtract: ";
- std::cin>>v;
- std::cout << "Value before subtract " << value << std::endl;
- value -= v;
- std::cout << "Value after subtract " << value << std::endl << std::endl;
- mementos.addMemento(getMemento());
- }
- void redo(){
- Memento* mem = mementos.redo();
- if(mem){
- std::cout << "Value before redo " << value << std::endl;
- value = mem->getState();
- std::cout << "Value after redo " << value << std::endl << std::endl;
- }
- }
- void undo(){
- Memento* mem = mementos.undo();
- if(mem){
- std::cout << "Value before undo " << value << std::endl;
- value = mem->getState();
- std::cout << "Value after undo " << value << std::endl << std::endl;
- }
- }
- };
- int main(){
- Value value(0);
- int decision = 0;
- std::string strDecision;
- do{
- std::cout << "What you want to do?" << std::endl << std::endl;
- std::cout << "Add [0]" << std::endl;
- std::cout << "Subtract [1]" << std::endl;
- std::cout << "Undo [2]" << std::endl;
- std::cout << "Redo [3]" << std::endl;
- std::cout << "Exit [4]" << std::endl;
- std::cin >> strDecision;
- decision = atol(strDecision.c_str());
- switch(decision){
- case 0:
- value.add();
- break;
- case 1:
- value.subtract();
- break;
- case 2:
- value.undo();
- break;
- case 3:
- value.redo();
- break;
- }
- }while(decision != 4);
- std::cin.get();
- return 0;
- }
Wynik działania powyższego kodu:
Memento was added! What you want to do? Add [0] Subtract [1] Undo [2] Redo [3] Exit [4] 0 Write some value to add: 1 Value before add 0 Value after add 1 Memento was added! What you want to do? Add [0] Subtract [1] Undo [2] Redo [3] Exit [4] 1 Write some value to subtract: 2 Value before subtract 1 Value after subtract -1 Memento was added! What you want to do? Add [0] Subtract [1] Undo [2] Redo [3] Exit [4] 2 Undo action! Value before undo -1 Value after undo 1 What you want to do? Add [0] Subtract [1] Undo [2] Redo [3] Exit [4] 2 Undo action! Value before undo 1 Value after undo 0 What you want to do? Add [0] Subtract [1] Undo [2] Redo [3] Exit [4] 2 You can not undo my old Yedi friend! What you want to do? Add [0] Subtract [1] Undo [2] Redo [3] Exit [4] 3 Redo action! Value before redo 0 Value after redo 1 What you want to do? Add [0] Subtract [1] Undo [2] Redo [3] Exit [4] 3 Redo action! Value before redo 1 Value after redo -1 What you want to do? Add [0] Subtract [1] Undo [2] Redo [3] Exit [4] 3 You can not redo my old Yedi friend! What you want to do? Add [0] Subtract [1] Undo [2] Redo [3] Exit [4]

Tytuł:
React 17. Wzorce projektowe i najlepsze praktyki. Projektowanie i rozwijanie nowoczesnych aplikacji internetowych. Wydanie III
Autor:
Carlos Santana Roldán

Tytuł:
Wzorce projektowe. Rusz głową! Tworzenie rozszerzalnego i łatwego w utrzymaniu oprogramowania obiektowego. Wydanie II
Autor:
Eric Freeman, Elisabeth Robson

Tytuł:
Wzorce projektowe w .NET Core 3. Projektowanie zorientowane obiektowo z wykorzystaniem C# i F#
Autor:
Dmitri Nesteruk

Tytuł:
Wzorce projektowe. Elementy oprogramowania obiektowego wielokrotnego użytku
Autor:
Erich Gamma, Richard Helm, Ralph Johnson, John Vlissides

Tytuł:
Projektowanie interfejsów., Sprawdzone wzorce projektowe. Wydanie III
Autor:
Jenifer Tidwell, Charles Brewer, Aynne Valencia-Brooks

Tytuł:
Kubernetes. Wzorce projektowe. Komponenty wielokrotnego użycia do projektowania natywnych aplikacji chmurowych
Autor:
Bilgin Ibryam, Roland Huß

Tytuł:
Wzorce projektowe w .NET. Projektowanie zorientowane obiektowo z wykorzystaniem C# i F#
Autor:
Dmitri Nesteruk

Tytuł:
Programowanie zorientowane obiektowo. Wzorce projektowe. Wydanie II
Autor:
Alan Shalloway, James R. Trott

Tytuł:
Java EE 8. Wzorce projektowe i najlepsze praktyki
Autor:
Rhuan Rocha, Joao Purificacao

Tytuł:
Systemy reaktywne. Wzorce projektowe i ich stosowanie
Autor:
Roland Kuhn Dr., Brian Hanafee, Jamie Allen