Паттерны GoF - Decorator/Wrapper (лекция)
Автор: Rageous
<MiF> Decorator
<MiF> он же Wrapper
<MiF> Назначение - динамически добавляет объекту новые обязанности, является гибкой альтернативой порождению потомков с целью расширения функциональность
<MiF> Использовать когда:
<MiF> 1. нужно динамическое расширение обязанностей объектов
<MiF> 2. когда расширение путем порождения подклассов затруднительно
<MiF> либо вообще невозможно
<MiF> Участники:
<MiF> 1. Component - компонент, определяет интерфейс для объектов, на которые динамически накладываются обязанности
<MiF> 2. ConcreteComponent - конкретный объект, на который могут быть возложены обязанности
<MiF> 3. Decorator - хранит ссылку на Component и определяет интерфейс, соответствующий Component
<MiF> 4. ConcreteDecorator - возлагает дополнительные обязанности на компонент, реализуя интерфейс
<MiF> Результаты:
<MiF> 1. по сравнению с наследованием гибкость больше, ибо можно даже рулить обязанность в runtime
<MiF> 2. можно постепенно наращивать функциональность добавлением новых декораторов
<MiF> Минусы: может наплодиться много мелких объектов
<Rageous> не помешает
<_NexiliaN_> да
<MiF> под Wrapper'ом часто понимают просто обвертку
<MiF> я какой-нибудь в меру абстрактный пример напишу
<MiF> http://www.everfall.com/paste/id.php?g9lqets5t92q
<Rageous> : public Stream????
<MiF> именно
<MiF> блин, надо двухуровневый пример
<Rageous> имхо там должно быть наследование от интерфейса
<Rageous> а не от декорируемого объекта
<xmvlad> да от интерфейса, должно быть
<MiF> http://www.everfall.com/paste/id.php?g9lqets5t92q
<Rageous> слышь
<MiF> ?
<Rageous> наследоваться надо от интерфейса
<Rageous> а не от оборачиваемого объекта
<MiF> ок, еще один уровень :)
<Rageous> =)
<_NexiliaN_> Stream* stream; Зачем?
<MiF> http://www.everfall.com/paste/id.php?g9lqets5t92q
<Rageous> чего-то ты опять перемудрил )
<Rageous> или я не так враппер понимаю
<MiF> имхо, сейчас все ништяк
<MiF> смотри
<MiF> есть например несколько реализация IStream
<MiF> в dll
<MiF> а тебе нужно надстроиться над ними, сохранив интерфейс
<xmvlad> теперь все так
<MiF> понятное дело, что отнаследоваться нельзя
<MiF> ну вот ты пишешь врапер
<MiF> он же декоратор :)
<Rageous> по-моему StreamWrapper там лишний - можно было отнаследовать от интерфейса PackedStream и сделать то же самое
<MiF> можно, но так стройнее
<MiF> допустим ты решил добавить новый стрим
<MiF> SuperPackedStream
<Rageous> ну да, я понимаю, можешь не объяснять
<MiF> ок
<MiF> у других вопросы есть?
<Rageous> только одно но...
<Rageous> кто мне мешает отнаследоваться от стрима вместо StreamWrapper-а?
<Rageous> ведь по сути враппер только прокидывает вызовы
<MiF> он в dll
<MiF> у меня только интерфейс
<MiF> для примера
<Rageous> т.е., в длл?
<Rageous> что мне мешает наследоваться от класса, который лежит в длл?
<Rageous> (при наличии хидера и либки)
<MiF> либки нет
<Rageous> не, чего-то ты загоняешься
<Rageous> паттерны не для с++ писались
<MiF> коммерческая либа например
<Rageous> ну как-то я этим классом же пользуюсь?
<MiF> есть dll, кода нет
<Rageous> для наследования нужен не код функций, а хидер
<Rageous> или я не прав?
<MiF> как ты будешь вызывать ConcreteStream::что-то
<MiF> ты хочешь задекорировать существующий ConcreteStream
<Rageous> да
<xmvlad> ваще пойнт другой, декоратор использует базовый интерфейс и добавляет какую-то функциональности, в результате может декорировать любой объект наследуемый от базового интерфейса
<Rageous> угу
<MiF> давай пример сделаю
<Rageous> а в чем различия с фасадом, кстати?
<MiF> а ты скажешь, как без декоратора
<Rageous> давай
<xmvlad> кхм, фасад вобще ни откуда не наследуется
<xmvlad> фасад это просто интерфейс для пользователя скрывающий сложную систему
<Rageous> понятна
<MiF> http://www.everfall.com/paste/id.php?zsfyhfojdjlv
<MiF> отдекарируй мне три этих стрима упаковкой
<MiF> без декоратора юзаем наследование
<MiF> ну и наследуемся три раза, плодим три класса
<MiF> это даже если наследоваться можно
<xmvlad> да, тема раскрыта, давай дальше :)
<Rageous> угу
<MiF> у остальных вопросы есть?
<kas> я потом покурю спрошу в форуме если что :)
<MiF> оки
22 января 2006