Архитектура движка.Статьи

Паттерны GoF - Memento (лекция)

Автор:

<MiF> Memento
<MiF> Назначение - не нарушая инкапсуляции позволяет фиксировать и вынести за пределы объекта его внутреннее состояние, чтобы потом можно было восстановит объект
<MiF> применять когда:
<MiF> 1. необходимо сохранить состояние объекта либо его части, чтобы потом объект можно было восстановить в этом же состоянии
<MiF> 2. прямое получение этого состояния нарушает инкапсуляцию
<MiF> Участники:
<MiF> 1. Memento - хранитель. Сохраняет внутренее состояние объекта Originator.
<MiF> Также он запрещает доступ к себе для всех, кроме хозяина
<MiF> 2. Originator - хозяин, создает хранителя. Использует его для восстановления состояния
<MiF> 3. Caretaker - посыльный, отвечает за сохранения хранителя, не знает его внутренее содержимое
<MiF> Результаты:
<MiF> 1. Позволяет избежать открытия информации, которую должен знать только хозяин, но которую нужно хранить вне него. Короче сохраняет инкапсуляцию
<MiF> 2. Можно сделать то же самое без всяких хранителей, но тогда придется усложнить структуру хозяина, и добавить в него функциональность для сохранения состояния
<MiF> Но при этом структура хозяина усложнится
<MiF> Короче паттерн хранитель позволяет упростить структуру хозяина
<MiF> Минусы понятны - хранители могут быть жирными и избыточными и кидать каждый раз в них данные будет медленно

  • MiF sets mode: -m
  • <MiF> Пример кода нужен
    <Padawan> Как переводится Memento ?
    <MiF> хранитель
    <Rageous> мне второй результат не очень понятен
    <Rageous> что значит "сделать без хранителей"?
    <MiF> Ну сам объект может хранить свои состояния и рулить их восстановлением
    <MiF> только для этого всю реализацию придется запихать в него
    <MiF> А так мы выносим это дело наружу
    <MiF> при этом не нарушая инкапсуляции
    <Rageous> хм... а кто сохраняет данные в хранителя? разве не сам объект?

  • Disconnected
  • Rejoined channel #gamedev_lecture
  • <Rageous> :( вылетел
    <Rageous> вопрос про применение хранетиля в геймдеве уже задали?
    <MiF> я пример кода ушел писать
    <Rageous> ок
    <MiF> сам не применял :)
    <MiF> а ты?
    <new_> я применял
    <Rageous> расскажи )
    <Rageous> мне в геймдеве не довелось
    <new_> для осуществления загрузки/сохранения
    <Rageous> а чем он там поможет?
    <new_> только там Caretaker'ом был std::iostream
    <MiF> короче Memento - отделение менеджемента состояний от самого объекта
    <Rageous> насколько я могу прикинуть, можно заюзать его в квик сейва: в отличие от обычного его нужно грузить быстро, а полная сериализация на диск и десериализация идут медленно. тогда можно оставить "слепок" уровня в хранителе, а его в памяти - тогда быстрая загрузка будет идти значительно быстрее
    <MiF> Rageous, отличная идея
    <Rageous> еще, как вариант, пошаговые игры с кнопкой "переиграть ход"
    <MiF> Ну для откатов он часто используется
    <Rageous> потом: да, инвентарь - что-то поперекладывали, не понравилось, все вернули
    <Rageous> по кнопке "отмена"
    <new_> я так и делал, просто менял ofstream на streangstream
    <MiF> Ладно, пойду напишу абстрактный пример
    <MiF> может понятнее станет
    <Rageous> угу, ждем )
    <Rageous> тож интересный вариант: перед началом игры конфигурим перца, а сохраненные пользователем конфигурации сохраняем в мементо. позже эти хранители можно скинуть на диск или дать пользователю выбрать один из созданных им и т.п. - т.к. хранитель может малой кровью описать целого перса, то хранение нескольких (и даже множества) в памяти вряд ли станет серьезной проблемой. единственное, конечно - восстановление состояния по хранителю тем медленнее, чем меньше хранитель занимает, потому придется некоторое время побаловаться балансом "скорость восстановления - вес хранителя" :)
    <MiF> http://www.everfall.com/paste/id.php?c4w9r836nv8a
    <MiF> вообщем смысл паттерна - вынос менджмента состояний объекта из самого объекта, при сохранении инкапсуляции
    <MiF> *менеджмента
    <Rageous> угу
    <MiF> вопросы есть?
    <Rageous> а Caretaker обязательная часть паттерна разве?
    <MiF> получается, что так
    <Rageous> мм... дай подумать
    <MiF> если хранить мементо в самом объекте - то смысла никакого нет
    <Rageous> почему я просто не могу получить хранителя от объекта в произвольном месте/класс?
    <Rageous> *классе
    <Rageous> Caretaker получается менеджером состояний, да, но кто мне мешает вообще обойтись без этого менеджмента, получения состояния по метке и т.п.?

  • Disconnected
  • Rejoined channel #gamedev_lecture
  • <MiF> нью, не понял
    <Rageous> блин, да че за....
    <Rageous> в общем, почему я просто не могу получить хранителя от объекта в произвольном месте/класс?
    <Rageous> [01:20:30] <Rageous> *классе
    <Rageous> [01:21:47] <Rageous> Caretaker получается менеджером состояний, да, но кто мне мешает вообще обойтись без этого менеджмента, получения состояния по метке и т.п.?
    <new_> в своём объекте что надо хранить?
    <new_> или от чего наследовать?
    <MiF> это скорее уже не мементо будет
    <Rageous> в общем, caretaker мне лично каким-то надуманным кажется
    <MiF> если нужно вынести хранителя за пределы объекта - то да, это Memento
    <MiF> в роли кейртейкера может выступать что угодно
    <MiF> что получает и хранит хранителей
    <Rageous> любой получатель хранителей, да
    <MiF> все, все согласны :)
    <Rageous> :)
    <MiF> new_ что не ясно?
    <MiF> как тебе использовать мементо?
    <new_> всё, всё понял :)
    <MiF> ок, поехали дальше

    22 января 2006