Stáhnout prezentaci
Prezentace se nahrává, počkejte prosím
ZveřejnilMilada Havlová
1
Memento
2
Obnovení operačního systému ( Windows | Linux...) Všichni víme, co jsou transekce v databázi Memento – zálohování databáze
3
Občas je potřeba udělat kroky zpět Memento –kroky zpět Dead move
4
Memento Známý také jako Token, Snapshot Účel Kategorie: behavioral patterns (vzory chování) Uchovávání vnitřního stavu objektu bez porušení zapouzdření Motivace Undo/rollback Checkpointy Pro dočasné operace nebo zotavení z chyb Použití Save/Load funkce ve hrách Transakce v databázích Složité matematické výpočty, při kterých se můžou ztratit dlouho počítaná data V grafických editorech, pro uchování stavu obrazovky při posouvaní objektů
5
Memento – struktura Struktura Účastníci Originator : Objekt, jehož vnitřní stav chceme uložit Memento : Reprezentuje uložené stavy Originátoru Caretaker : Řídí ukládání/načítání Mementa do/z Originátoru
6
Memento – účastníci Memento Uchovává vnitřní stav Originátoru Implementuje 2 různá rozhraní: Wide Interface – pro Originator Narrow Interface – pro Caretaker Chrání privátní data Originátora Originátor Vytváří Memento pro uchování svého vnitřního stavu Používá Memento pro obnovení svého vnitřního stavu Caretaker Je zodpovědný za uchování Mementa Nevidí obsah Mementa
7
Memento – interakce Caretaker požádá Originator o Memento. Nějaký čas jej podrží a pak vrátí zpátky Originátoru.
8
Memento – souvislosti Vlastnosti Uchovává vnitřní stav objektu a umožňuje jeho pozdější obnovení Uchovává stav mimo vlastní objekt Zjednodušuje Originator Zabraňuje odhalení vnitřních částí Originátoru Caretaker může aplikovat různé strategie pro uchovávání/zahazování Může být paměťově náročné Je úzce svázané s typem objektu, jehož obsah si pamatuje Definice dvou různých rozhraní může být v některých jazycích složitá
9
C++ Memento – privátní metody Zpřístupněné Originátoru pomocí klíčového slova friend class Originator { public: Memento* createMemento(); void setMemento(const Memento*); private: State* state_; }; class Memento { public: virtual ~Memento(); private: friend class Originator; Memento(); void setState(State*); State* getState(); private: State* state_; }; Metody zpřístupněné Originátoru Memento – implementace
10
Java Memento je vnitřní třída třídy Originator Bez problémů přistoupí k privátním položkám třídy Originator class Originator { private String state; public void set(String state) { this.state = state; } public Memento getMemento() { return new Memento(state); } public void restoreFromMemento(Memento memento) { state = memento.getSavedState(); } public static class Memento { private final String state; private Memento(String stateToSave) { state = stateToSave; } private String getSavedState() { return state; } Memento – implementace
11
C# // Originator [Serializable()] class Originator { List state = new List (); public void Operation (string s) { state.Add(s); foreach (string line in state) Console.WriteLine(line); Console.WriteLine("======================="); } // The reference to the memento is passed back to the client public Memento SetMemento() { Memento memento = new Memento(); return memento.Save(state); } public void GetMemento(Memento memento) { state = (List ) memento.Restore(); } Memento – implementace [Serializable()] // Serializes by deep copy to memory and back class Memento { MemoryStream stream = new MemoryStream(); BinaryFormatter formatter = new BinaryFormatter(); public Memento Save (object o) { formatter.Serialize(stream, o); return this; } public object Restore() { stream.Seek(0, SeekOrigin.Begin); object o = formatter.Deserialize(stream); stream.Close(); return o; } class Caretaker { public Memento Memento {get; set;} }
12
Memento – implementace Serializace Levný způsob zachycení aktuálního stavu Originátoru Snazší perzistence Ukládání přírůstkových změn Memento obsahuje změny vůči předcházejícímu stavu Originator musí dostat Mementa ve správném pořadí Můžeme kombinovat přírůstková Mementa s Mementy obsahujícími plný stav
13
Memento – příklady Kalkulačka s funkcí undo Uživatel chce mít možnost vrátit se zpátky ve výpočtu Ne všechny funkce jsou inverzní – je nutno použít Memento Zabrání opakování složitých výpočtů při chybě uživatele
14
Memento – příklady class CalculatorMemento { private: friend class Calculator; CalculatorMemento(); CalculatorMemento(const int value) : value_(value) { } void setState(const int value) { value_ = value; } int getState() const { return value_; } int value_; } Kalkulačka – Memento Stav Originátoru. Hodnota na kalkulačce Zabrání vytváření Mementa mimo Originator
15
Memento – příklady class Calculator { public: Calculator() : value_(0) { } void execute(const Command command, const int value) {... } const CalculatorMemento *createMemento() { return new CalculatorMemento(value_); } void setMemento(const CalculatorMemento *m) { value_ = m->getState(); } private: int value_; }; Kalkulačka – Originator Originator se nestará o objekt Mementa
16
Memento – příklady class CalculatorWithUndo { public: void execute(const Command command, const int value) { undoStack_.push(calculator_.createMemento()); calculator_.execute(command, value); } void undo() { if (!undoStack_.empty()) { const CalculatorMemento *m = undoStack_.top(); calculator_.setMemento(m); delete m; undoStack_.pop(); } private: std::stack undoStack_; Calculator calculator_; }; Kalkulačka s funkcí undo – Caretaker Uložení stavu před vykonáním příkazu Caretaker má zodpovědnost za objekt Mementa Zásobník pro jednotlivá Mementa a undo operace
17
Memento – příklady class Game { // nine spaces char[] board = { 'X', '1', '2', '3', '4', '5', '6', '7', '8', '9' }; public void Play(int pos) { } // The reference to the memento is passed back to the client public Memento Save() { Memento memento = new Memento(); return memento.Save(board); } public void Restore(Memento memento) { board = (char[])memento.Restore(); Player = board[0]; } public void DisplayBoard() { } Piškvorky s funkcí undo C# – Originator
18
Memento – příklady [Serializable()] // Serializes by deep copy to memory and back class Memento { MemoryStream stream = new MemoryStream(); static BinaryFormatter formatter = new BinaryFormatter(); public Memento Save(object o) { formatter.Serialize(stream, o); return this; } public object Restore() { stream.Seek(0, SeekOrigin.Begin); object o = formatter.Deserialize(stream); stream.Close(); return o; } Piškvorky s funkcí undo C# – Memento a Caretaker class Caretaker { public Memento Memento { get; set; } }
19
Memento – shrnutí Kdy užít Memento Je-li potřeba zachovat vnitřní stav objektu Je-li nepřípustné porušit zapouzdření Související návrhové vzory Command Užívá Memento pro vrácení při nevratných operacích Iterator Mementa mohou být použita pro iteraci
Podobné prezentace
© 2024 SlidePlayer.cz Inc.
All rights reserved.