Обсуждение:Декоратор (шаблон проектирования)

Материал из Википедии — свободной энциклопедии
Перейти к навигации Перейти к поиску

Диаграмма UML[править код]

Предлагаю заменить существующую диаграмму

(которая на самой странице статьи показана в виде превьюшки, так что прочитать её можно только, перейдя к оригинальному варианту) на эту диаграмму

или увеличить читаемость исходной диаграммы. В противном случае сложно читать разделы Участники и Следствия (тяжело воспринимаются отношения между классами). ivannesl 14:39, 26 декабря 2008 (UTC)[ответить]

На старой диаграмме в листочках с загнутым уголком написано тело функции, а пунктирная линия с кружком на конце показывает какому заголовку функции принадлежит это описание. На новой диаграмме, на которую предлагается заменить существующую, соответствия между телом функции и её заголовком не видно. Поэтому надо или доработать новую диаграмму, или просто добавить где-нибудь на странице существующую в полном размере, чтобы её было видно. Хотя меня лично не напрягает нажать на превью правой кнопкой мыши и открыть картинку в новом окне.
mrZmey 14:57, 7 мая 2010 (UTC)[ответить]

Переопределять нужно все методы?[править код]

Что-то я не пойму из статьи: если есть сложный объект, у которого десяток методов, но из них только один нужно дополнить, то в декораторе придется переопределять все равно все методы? Не через чур ли это для добавления какой-то рамочки?OneHalf 19:56, 6 сентября 2010 (UTC)[ответить]

Получается это всё один шаблон?[править код]

Известен также под менее распространённым названием Обёртка (Wrapper)
А вот из статьи про Адаптер
Адаптер, Adapter или Wrapper/Обёртка — структурный ...
Получается это всё один шаблон?178.95.7.165 12:24, 24 апреля 2013 (UTC)[ответить]

The "Adapter" pattern is also known as "Wrapper" pattern (WrapperPattern). Is Wrapper/Adapter/Decorator the same pattern?
No. AdapterPattern is used to convert the interface of an object into something else. DecoratorPattern is used to extend the functionality of an object while maintaining its interface. Both of these are probably sometimes called WrapperPattern since both of them do "wrap" an object. (link) 2.95.130.41 16:53, 8 апреля 2014 (UTC)[ответить]

Delphi/Free Pascal[править код]

В Delphi/Free Pascal есть понятие class helper, который позволяет максимально просто расширить функционал объекта, не создавая подклассов и не используя никаких шаблонов.

TMyObject = class
  procedure ReadData(const Stream: TStream);
end;

TMyObjectHelper = class helper for TMyObject
  procedure ReadData(const FileName: string); overload;
end;

... 
 
var
  o: TMyObject;
begin
  o := TMyObject.Create;
  try
    o.ReadData(SomeStream);
    o.ReadData(SomeFileName);
  finally
    o.Free;
  end;
end.

Delphi/FreePascal: Ограничения class helpers[править код]

Действительно, в языке Delphi есть такая технология как class helpers, однако она существенно менее гибкая, нежели "настоящий" Decorator. Давайте рассмотрим пример, который мне был очень нужен: Имеется поток (TStream). Это может быть как TMemoryStream, получаемый из сети, так и TFileStream, получаемый из локального файла. Требуется: оба этих потока представить как текстовые файлы, то есть читать данные из них построчно, командами Readln.

Решение с помощью class helpers позволяет добавить к TStream метод Readln, но возникнет существенная сложность: при чтении текстового файла обычно (даже в "родном" паскалевском TextFile) используется чтение большими блоками, в котором уже производится поиск строки. В случае class helpers внедрение буфера (и связанных данных: реальный объём буфера и позиция "читающего" курсора) невозможно, что негативно скажется на производительности решения: потребуется вычитывать небольшой буфер, а потом "возвращать" указатель позиции в потоке и при следующем чтении вновь читать блок, который раньше уже был вычитан.

В дополнение к class helpers можно использовать также writeable constants, храня непосредственно в процедуре хелпера некоторые данные (например, тот же буфер и указатель). Тем не менее, этот метод - одно из худших зол, которое может существовать, в связи с тем, что полученный класс будет непотокобезопасен, да и вообще - не будет работать, если два или более экземпляра объекта будут использовать этот хелпер одновременно. Так что приведённое решение только усугубляет проблему.

Настоящий же Decorator с успехом решает проблему: он позволяет добавить как дополнительный функционал (Readln), так и сохранить существующий (нужно помнить, что при выполнении "реального" Read/Write/Seek требуется сперва "открутить" буфер назад и только потом вызывать декорируемый метод). Тем самым, несмотря на то, что class helpers внешне похожи на Decorator, "внутри" они несколько отличаются, а в более старых Delphi, где такой технологии ещё не было - использовались просто функции, первым параметром которым передавался "декорируемый" объект. Ровно такую же методику можно применять для "декорирования" объектов в любом другом языке программирования, поддерживающем свободные процедуры, только надо помнить: никаких связанных данных хранить не получится.

SmiSoft 17:08, 20 мая 2016 (UTC)[ответить]

SmiSoft

Отличие от наследования[править код]

В статье говорится: "Шаблон Декоратор предоставляет гибкую альтернативу практике создания подклассов с целью расширения функциональности." - однако в примере (на Java, в остальных не шарю) используется именно наследование с переопределением методов. :-| Надо бы либо описание уточнить, либо пример переделать! Konradddd (обс.) 17:57, 24 апреля 2022 (UTC)[ответить]