Зні́мок (англ. Memento) — це шаблон проєктування, що належить до класу шаблонів поведінки і забезпечує можливість відновлення об'єкта до збереженого (попереднього) стану.
Призначення
Не порушуючи інкапсуляції, фіксує та виносить за межі об'єкта його внутрішній стан так, щоб пізніше можна було відновити з нього об'єкт.
Застосування
Слід використовувати шаблон Знімок у випадках, коли:
- необхідно зберегти миттєвий знімок стану об'єкта (або його частини), щоб згодом об'єкт можна було відтворити у тому ж самому стані;
- безпосереднє вилучення цього стану розкриває деталі реалізації та порушує інкапсуляцію об'єкта.
Структура
- Memento — контекст:
- зберігає внутрішній стан об'єкта Originator. Обсяг інформації, що зберігається, може бути різним та визначається потребами хазяїна;
- забороняє доступ усім іншим об'єктам окрім хазяїна. По суті знімок має два інтерфейси. Опікун Caretaker користується лише вузьким інтерфейсом знімку — він може лише передавати знімок іншим об'єктам. Навпаки, хазяїн користується широким інтерфейсом, котрий забезпечує доступ до всіх даних, необхідних для відтворення об'єкта (чи його частини) у попередньому стані. Ідеальний варіант — коли тільки хазяїну, що створив знімок, відкритий доступ до внутрішнього стану знімку;
- Originator — хазяїн:
- створює знімок, що утримує поточний внутрішній стан;
- використовує знімок для відтворення внутрішнього стану;
- CareTaker — опікун:
- відповідає за зберігання знімка;
- не проводить жодних операцій над знімком та не має уявлення про його внутрішній зміст.
Відносини
- опікун запитує знімок у хазяїна, деякий час тримає його у себе, опісля повертає хазяїну. Іноді цього не відбувається, бо хазяїн не має необхідності відтворювати свій попередній стан;
- знімки пасивні. Тільки хазяїн, що створив знімок, має доступ до інформації про стан.
Переваги
- Забезпечує спосіб запису внутрішнього стану об'єкта в окремому об'єкті, не порушуючи закону дизайну.
- Усуває потребу в багаторазовому створенні того ж об'єкта з єдиною метою збереження його стану.
- Спрощує Originator, даючи відповідальність за зберігання Memento серед Caretaker.
Недоліки
- Збереження та відновлення стану може зайняти багато часу.
- Об'єкт Memento повинен забезпечувати два типи інтерфейсів: вузький інтерфейс для Caretaker і широкий інтерфейс для Originator.
- Дозволяє іншому об'єкту довільно змінити стан об'єкта
Реалізація
C++
#include <iostream> #include <array> #include <Windows.h> using namespace std; // Стан містить здоров’я та кількість убитих монстрів struct State { float health; int amount_of_killed; State() :health(100), amount_of_killed(0) {}; friend ostream& operator<<(ostream & os, const State & s) { return os << "Health: " << s.health << " , killed " << s.amount_of_killed << '\n'; } }; // Memento — контекст // зберігає внутрішній стан об'єкта Originator class GameMemento { private: State state; public: GameMemento() {} GameMemento(State s) :state(s) {} State get_state() { return state; } }; // Originator — хазяїн // створює знімок, що утримує поточний внутрішній стан; // використовує знімок для відтворення внутрішнього стану; class GameOriginator { private: // Стан містить здоров’я та кількість убитих монстрів State state; public: void play() { // Імітуємо процес гри — // здоров’я повільно погіршується, а монстрів стає все менше state.health *= 0.9; state.amount_of_killed += 2; cout << state; } GameMemento game_save() { return GameMemento(state); } void load_game(GameMemento memento) { state = memento.get_state(); } }; //CareTaker — опікун //відповідає за зберігання знімка; //не проводить жодних операцій над знімком та не має уявлення про його внутрішній зміст. class Caretaker { private: GameOriginator game; array< GameMemento, 5 > quick_saves; int k; bool save_load; void check_save() { k < 5 ? k++ : k = 0; } // метод аби побачити коли була здійснена загрузка void check_load() { if (save_load == true) { SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_GREEN); save_load = false; } else { SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE); } } public: Caretaker() : k(-1) {} void shoot() { check_load(); game.play(); } void F5() { check_save(); quick_saves[k] = game.game_save(); } void F9(int i = -1) { if (i < 0 || i > 5) i = k; game.load_game(quick_saves.at(i)); save_load = true; } }; void main() { Caretaker player; player.F5(); player.shoot(); player.F5(); player.shoot(); player.shoot(); player.shoot(); player.shoot(); player.F9(); player.shoot(); player.shoot(); player.F5(); player.F9(2); player.shoot(); player.shoot(); }
Джерела
- Design Patterns: Elements of Reusable Object-Oriented Software [ 9 листопада 2012 у Wayback Machine.]
- Андрій Будай Дизайн-патерни — просто, як двері [ 10 жовтня 2020 у Wayback Machine.]. — 2012. — 90 с.
Література
Алан Шаллоуей, Джеймс Р. Тротт. Шаблоны проектирования. Новый подход к объектно-ориентированному анализу и проектированию = Design Patterns Explained: A New Perspective on Object-Oriented Design. — М. : «Вильямс», 2002. — 288 с. — .
Вікіпедія, Українська, Україна, книга, книги, бібліотека, стаття, читати, завантажити, безкоштовно, безкоштовно завантажити, mp3, відео, mp4, 3gp, jpg, jpeg, gif, png, малюнок, музика, пісня, фільм, книга, гра, ігри, мобільний, телефон, android, ios, apple, мобільний телефон, samsung, iphone, xiomi, xiaomi, redmi, honor, oppo, nokia, sonya, mi, ПК, web, Інтернет
Zni mok angl Memento ce shablon proyektuvannya sho nalezhit do klasu shabloniv povedinki i zabezpechuye mozhlivist vidnovlennya ob yekta do zberezhenogo poperednogo stanu PriznachennyaNe porushuyuchi inkapsulyaciyi fiksuye ta vinosit za mezhi ob yekta jogo vnutrishnij stan tak shob piznishe mozhna bulo vidnoviti z nogo ob yekt ZastosuvannyaSlid vikoristovuvati shablon Znimok u vipadkah koli neobhidno zberegti mittyevij znimok stanu ob yekta abo jogo chastini shob zgodom ob yekt mozhna bulo vidtvoriti u tomu zh samomu stani bezposerednye viluchennya cogo stanu rozkrivaye detali realizaciyi ta porushuye inkapsulyaciyu ob yekta StrukturaUML diagrama sho opisuye strukturu shablonu proyektuvannya Znimok Memento kontekst zberigaye vnutrishnij stan ob yekta Originator Obsyag informaciyi sho zberigayetsya mozhe buti riznim ta viznachayetsya potrebami hazyayina zaboronyaye dostup usim inshim ob yektam okrim hazyayina Po suti znimok maye dva interfejsi Opikun Caretaker koristuyetsya lishe vuzkim interfejsom znimku vin mozhe lishe peredavati znimok inshim ob yektam Navpaki hazyayin koristuyetsya shirokim interfejsom kotrij zabezpechuye dostup do vsih danih neobhidnih dlya vidtvorennya ob yekta chi jogo chastini u poperednomu stani Idealnij variant koli tilki hazyayinu sho stvoriv znimok vidkritij dostup do vnutrishnogo stanu znimku Originator hazyayin stvoryuye znimok sho utrimuye potochnij vnutrishnij stan vikoristovuye znimok dlya vidtvorennya vnutrishnogo stanu CareTaker opikun vidpovidaye za zberigannya znimka ne provodit zhodnih operacij nad znimkom ta ne maye uyavlennya pro jogo vnutrishnij zmist VidnosiniUML diagrama sho opisuye vidnosini mizh ob yektami shablonu proyektuvannya Znimok opikun zapituye znimok u hazyayina deyakij chas trimaye jogo u sebe opislya povertaye hazyayinu Inodi cogo ne vidbuvayetsya bo hazyayin ne maye neobhidnosti vidtvoryuvati svij poperednij stan znimki pasivni Tilki hazyayin sho stvoriv znimok maye dostup do informaciyi pro stan PerevagiZabezpechuye sposib zapisu vnutrishnogo stanu ob yekta v okremomu ob yekti ne porushuyuchi zakonu dizajnu Usuvaye potrebu v bagatorazovomu stvorenni togo zh ob yekta z yedinoyu metoyu zberezhennya jogo stanu Sproshuye Originator dayuchi vidpovidalnist za zberigannya Memento sered Caretaker NedolikiZberezhennya ta vidnovlennya stanu mozhe zajnyati bagato chasu Ob yekt Memento povinen zabezpechuvati dva tipi interfejsiv vuzkij interfejs dlya Caretaker i shirokij interfejs dlya Originator Dozvolyaye inshomu ob yektu dovilno zminiti stan ob yektaRealizaciyaC Priklad realizaciyi na movi S include lt iostream gt include lt array gt include lt Windows h gt using namespace std Stan mistit zdorov ya ta kilkist ubitih monstriv struct State float health int amount of killed State health 100 amount of killed 0 friend ostream amp operator lt lt ostream amp os const State amp s return os lt lt Health lt lt s health lt lt killed lt lt s amount of killed lt lt n Memento kontekst zberigaye vnutrishnij stan ob yekta Originator class GameMemento private State state public GameMemento GameMemento State s state s State get state return state Originator hazyayin stvoryuye znimok sho utrimuye potochnij vnutrishnij stan vikoristovuye znimok dlya vidtvorennya vnutrishnogo stanu class GameOriginator private Stan mistit zdorov ya ta kilkist ubitih monstriv State state public void play Imituyemo proces gri zdorov ya povilno pogirshuyetsya a monstriv staye vse menshe state health 0 9 state amount of killed 2 cout lt lt state GameMemento game save return GameMemento state void load game GameMemento memento state memento get state CareTaker opikun vidpovidaye za zberigannya znimka ne provodit zhodnih operacij nad znimkom ta ne maye uyavlennya pro jogo vnutrishnij zmist class Caretaker private GameOriginator game array lt GameMemento 5 gt quick saves int k bool save load void check save k lt 5 k k 0 metod abi pobachiti koli bula zdijsnena zagruzka void check load if save load true SetConsoleTextAttribute GetStdHandle STD OUTPUT HANDLE FOREGROUND GREEN save load false else SetConsoleTextAttribute GetStdHandle STD OUTPUT HANDLE FOREGROUND RED FOREGROUND GREEN FOREGROUND BLUE public Caretaker k 1 void shoot check load game play void F5 check save quick saves k game game save void F9 int i 1 if i lt 0 i gt 5 i k game load game quick saves at i save load true void main Caretaker player player F5 player shoot player F5 player shoot player shoot player shoot player shoot player F9 player shoot player shoot player F5 player F9 2 player shoot player shoot DzherelaDesign Patterns Elements of Reusable Object Oriented Software 9 listopada 2012 u Wayback Machine Andrij Budaj Dizajn paterni prosto yak dveri 10 zhovtnya 2020 u Wayback Machine 2012 90 s LiteraturaAlan Shallouej Dzhejms R Trott Shablony proektirovaniya Novyj podhod k obektno orientirovannomu analizu i proektirovaniyu Design Patterns Explained A New Perspective on Object Oriented Design M Vilyams 2002 288 s ISBN 0 201 71594 5