Прочитал у GoF о паттерне memento (хранитель). Мне его полезность показалась сомнительной. Зачем создавать специальный класс для сохранения состояния объектов, если можно просто сохранять копии этих объектов. Разве что в случае когда конструктор копий и оператор прасваивания необходимо слелать закрытыми и/или вообще не реализововать (как,например, в singleton'е). Может быть я что-то не уловил?
Здравствуйте, kvas, Вы писали:
K>Прочитал у GoF о паттерне memento (хранитель). Мне его полезность показалась сомнительной. Зачем создавать специальный класс для сохранения состояния объектов, если можно просто сохранять копии этих объектов.
Разве что в случае когда конструктор копий и оператор прасваивания необходимо слелать закрытыми и/или вообще не реализововать (как,например, в singleton'е). Может быть я что-то не уловил?
Все ессно IMHO !
На самом деле, паттерны выше, чем просто способ реализации, и описывают высокоуровневую проблему (ее типизацию) и высокоуровневый подход к решению.
Поэтому, ты можешь создавать отдельный класс, можешь маршалить(анмаршалить) и в ФС, и в БД итд, но смысл остается один.
Так, например, паттерны Decorator и Proxy , имеют обычно схожую реализацию, но смысловую нагрузку совсем разную.
Основное назначание паттернов — улучшение коммуникации между членами команды
Здравствуйте, kvas, Вы писали:
K>Прочитал у GoF о паттерне memento (хранитель). Мне его полезность показалась сомнительной. Зачем создавать специальный класс для сохранения состояния объектов, если можно просто сохранять копии этих объектов. Разве что в случае когда конструктор копий и оператор прасваивания необходимо слелать закрытыми и/или вообще не реализововать (как,например, в singleton'е). Может быть я что-то не уловил?
ну, например, есть какие-то поля, которые сохранять не нужно или нельзя
Здравствуйте, jazzer, Вы писали:
J>Здравствуйте, kvas, Вы писали:
K>>Прочитал у GoF о паттерне memento (хранитель). Мне его полезность показалась сомнительной. Зачем создавать специальный класс для сохранения состояния объектов, если можно просто сохранять копии этих объектов. Разве что в случае когда конструктор копий и оператор прасваивания необходимо слелать закрытыми и/или вообще не реализововать (как,например, в singleton'е). Может быть я что-то не уловил?
J>ну, например, есть какие-то поля, которые сохранять не нужно или нельзя
Рассмотрим для примера использование memento и operator =
Originator obj1, obj2;
//здесь как-то изменяем obj1
Memento mem = obj1.CreateMemento();
obj2.SetMemento(mem); // теперь obj1 == obj2 с точностью до реализации operator ==
Originator obj1, obj2;
//здесь как-то изменяем obj1
obj2 = obj1; // теперь obj1 == obj2 с точностью до реализации operator ==
И в первом и во втором случае operator == должен возвращать true.
Т.е. если какие-то поля memento не сохраняет, то эти поля не должны учавствовать в операции сравнения. Это по какой-же причине? Например, если используется какое-то кеширование и operator = копирует и кеш, а memnto нет. Не столь распространенный случай что-бы включать его в каталог паттернов, как мне кажется.
K>Рассмотрим для примера использование memento и operator =
[] K>И в первом и во втором случае operator == должен возвращать true. K>Т.е. если какие-то поля memento не сохраняет, то эти поля не должны учавствовать в операции сравнения. Это по какой-же причине? Например, если используется какое-то кеширование и operator = копирует и кеш, а memnto нет. Не столь распространенный случай что-бы включать его в каталог паттернов, как мне кажется.
Не только кэширование. Например, объект может при создании захватывать ресурсы (скажем, открывать в эксклюзивном режиме файл, имя которого передается в конструкторе). Тогда скопировать объект будет не так-то просто: придется помнить о том, что некоторые объекты -- "фантомы", они не отвечают за освобождение ресурсов, или заводить счетчики ссылок etc.; продумывать политику освобождения ресурсов (кто должен освобождать в твоем примере -- obj1 или obj2?). То есть мы придем к тому, что есть полноценные объекты и есть "фантомы", которые нужны для сохранения состояния полноценных объектов. А зачем усложнять логику класса, если можно завести отдельный, который и будет отвечать только за сохранение состояния объектов нашего класса?
Д.К. << RSDN@Home 1.1.4 beta 2>> слушаем silent
Все на свете должно происходить медленно и неправильно...
Re: memento. Зачем?
От:
Аноним
Дата:
08.09.04 10:21
Оценка:
Здравствуйте, kvas, Вы писали:
K>Зачем создавать специальный класс для сохранения состояния объектов, если можно просто сохранять копии этих объектов.
Копия объекта — это частный случай реализации этого паттерна.
Состояние здесь инкапсулировано в объекте Memento и если внутри (что уже выходит за рамки данного паттерна) Memento хранит копию — ну ради бога. Up to you.
Здравствуйте, kvas, Вы писали:
K>Прочитал у GoF о паттерне memento (хранитель). Мне его полезность показалась сомнительной.
Например, если memento — это бинарный поток, то умение объекта записаться в бинарный поток а потом из него прочитаться уже есть первый шаг на пути к полной персистентности системы. Ведь этот поток легко можно сохранить в файл на жестком диске или передать по сети на другую машину.
Здравствуйте, kvas, Вы писали:
K>Прочитал у GoF о паттерне memento (хранитель). Мне его полезность показалась сомнительной. Зачем создавать специальный класс для сохранения состояния объектов, если можно просто сохранять копии этих объектов. Разве что в случае когда конструктор копий и оператор прасваивания необходимо слелать закрытыми и/или вообще не реализововать (как,например, в singleton'е). Может быть я что-то не уловил?
Да. Тонкость во-первых в том, что не все состояние объекта можно/нужно хранить для воспроизведения его клона. Различные кэши и временные объекты могут использоваться для ускорения реакции объекта на события. При хранении объект нужно перевести в "походное" положение, при котором оптимизирован занимаемый объем — быстродействие нам сейчас неважно. Паттерн позволяет переключаться между этими "походным" и "боевым" состояниями.
Во-вторых, существование объекта само по себе может иметь побочные эффекты. Например, на статистику "количество объектов класса С в системе". Или, например, он может удерживать указатель на другой объект, не давая его уничтожить. Паттерн мементо позволяет сохранить информацию о том, каким был объект в определенный момент, без побочных эффектов.
... << RSDN@Home 1.1.4 beta 1 >>
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re: Что означает понятие skills в резюме для работодателя?
Здравствуйте, kvas, Вы писали:
K>Прочитал у GoF о паттерне memento (хранитель). Мне его полезность показалась сомнительной. Зачем создавать специальный класс для сохранения состояния объектов, если можно просто сохранять копии этих объектов. Разве что в случае когда конструктор копий и оператор прасваивания необходимо слелать закрытыми и/или вообще не реализововать (как,например, в singleton'е). Может быть я что-то не уловил?
Одним из приятных следствий использования этого паттерна является возможность ассоциации множества объектов с одним объектом состояния (например, look-and-feel графических компонент).
Здравствуйте, kvas, Вы писали:
K>Прочитал у GoF о паттерне memento (хранитель). Мне его полезность показалась сомнительной. Зачем создавать специальный класс для сохранения состояния объектов, если можно просто сохранять копии этих объектов. Разве что в случае когда конструктор копий и оператор прасваивания необходимо слелать закрытыми и/или вообще не реализововать (как,например, в singleton'е). Может быть я что-то не уловил?
Я использовал Memento в проекте на C#. Ситуация была следующая.
В памяти строился "Компоновщик". Естественно, что каждый компонент хранил ссылки на дочерние компоненты. Дочерние компоненты естественно различных типов .
Потребовалось реализовать сериализацию/десериализацию композиции в Xml-документ и LDAP, а также передачу объекта по TCP-потоку. Для сохранения в Xml можно было просто сериализовать стандартными средствами .NET. А вот как быть с LDAP и TCP? И как максимально унифицировать процесс, чтобы не пришлось писать 3 различных механизма?
Дополнительной проблемой явилось то, что часть свойств компонентов не могла быть преобразована к string для успешного сохранения/восстановления из Xml/LDAP/TCP. Их надо предварительно сконвертировать в string.
Было принято следующее решение:
1. Каждый компонент возвращает Memento.
2. Этот Memento содержит только поля и свойства с примитивными типами данные (int/double/string) которые легко могут быть преобразованы в/из string. Ссылки на объекты заменяются либо символическими именами либо guid.
3. Для сериализации/десериализации используется только Memento.
Как результат, мы смогли обеспечить не только сериализацию/десериализацию композиции, но и передачу этой композиции на удаленную Unix-машину по TCP-каналу в виде документа Xml.
Классическая ошибка, которую совершают проектировщики абсолютно надежных систем, — недооценка изобретательности клинических идиотов.