Evgenii Legotckoi
Evgenii LegotckoiSept. 26, 2018, 6:01 a.m.

Structural Design Patterns - Decorator

Goals

  • Add additional features and functionality to the object dynamically. Decorators provide a flexible alternative to subclassing for extending functionality.
  • Client-specified decoration of the interface of the main object by recursively wrapping it.
  • Wrap the gift, put it in the box and wrap the box.

Problems

You want to add behavior or state to individual objects at run time. Inheritance is not possible because it is static and applies to the entire class.


Discussion

Let's say you're working with a user interface toolkit and you want to support adding borders and scrollbars to windows. You can define an inheritance hierarchy like...

But the Decorator pattern suggests giving the client the ability to specify any combination of "features".

Widget* aWidget = new BorderDecorator(
  new HorizontalScrollBarDecorator(
    new VerticalScrollBarDecorator(
      new Window( 80, 24 ))));
aWidget->draw();

This flexibility can be achieved with the following design

Another example of using cascaded (or chained) functions to create a custom object might look like this.

Stream* aStream = new CompressingStream(
  new ASCII7Stream(
    new FileStream("fileName.dat")));
aStream->putString( "Hello world" );

The solution to this class of problems involves encapsulating the original object inside an abstract wrapper interface. Both the decorator object and the main object inherit from this abstract interface. The interface uses recursive composition, allowing you to add an unlimited number of decorator "layers" to each main object.

Note that this pattern allows you to add functionality to an object, not to the object's interface. The interface presented to the client must remain constant as successive layers are specified.

Also note that the identity of the main object is now "hidden" inside the decorator object. Trying to directly access the underlying object is now a problem.

Structure

The client is always interested in the CoreFunctionality.doThis() method. The client may or may not be interested in OptionalOne.doThis() and OptionalTwo.doThis(). Each of these classes always delegates to the base Decorator class, and this class always delegates to the wrapper object.

Example

A decorator adds additional functionality to an object dynamically. Examples of decorators are decorations that are added to pine or spruce. Lights, garland, candy canes, glass ornaments, etc. These can be added to a tree to give it a festive look. Decorations do not change the tree itself, which can be recognized as a Christmas tree no matter what decorations are used. As an example of additional functionality, adding lights allows you to "light up" the Christmas tree.

Another example: an assault pistol is a lethal weapon. But you can apply certain "decorations" to make it more accurate, quiet and destructive.

Control List

  1. Make sure you have a context: one of the main (or optional) components, a few additional decorations or wrappers, and an interface common to all.
  2. Create the lowest level interface (LCD class) that makes all classes interchangeable.
  3. Create a second-level base class (Decorator) to support optional wrapper classes.
  4. The Core class and the Decorator class inherit from the LCD interface.
  5. The Decorator class declares a composition relation to the LCD interface, and this data member is initialized in its constructor.
  6. The Decorator class delegates the LCD object.
  7. Define a derived Decorator class for each additional embellishment.
  8. Derived Decorator classes implement their wrapper functionality - and - delegate to the base Decorator class.
  9. The client configures the type and order of the Core and Decorator objects.

Rules of thumb

  • An adapter provides a different interface to its object. The proxy provides the same interface. The decorator provides an extended interface.
  • The adapter changes the interface of the object, the Decorator extends the functionality of the object. The decorator is thus more transparent to the client. As a consequence, the Decorator supports recursive composition, which is not possible with pure adapters.
  • The composer and decorator have similar structure diagrams, reflecting the fact that both rely on recursive composition to organize an open number of objects.
  • A decorator can be thought of as a degenerate layout with a single component. However, the Decorator adds additional functionality - it is not designed for object aggregation.
  • Decorator is for adding functionality to objects without subclassing them. The purpose of the linker is not decoration, but presentation. These intentions differ from each other, but complement each other. Hence, the layout and decorator are often used together.
  • Composite can use Chain of Responsibility to allow components to access global properties through their parent. It can also use a Decorator to override these properties piece by piece.
  • Decorators and proxies have different purposes but similar structures. Both describe how to provide an abstraction layer to another object, and the implementations contain a reference to the object to which they direct requests.
  • A decorator allows you to change the representation of an object.
We recommend hosting TIMEWEB
We recommend hosting TIMEWEB
Stable hosting, on which the social network EVILEG is located. For projects on Django we recommend VDS hosting.

Do you like it? Share on social networks!

Comments

Only authorized users can post comments.
Please, Log in or Sign up
d
  • dsfs
  • April 26, 2024, 4:56 a.m.

C ++ - Test 004. Pointers, Arrays and Loops

  • Result:80points,
  • Rating points4
d
  • dsfs
  • April 26, 2024, 4:45 a.m.

C++ - Test 002. Constants

  • Result:50points,
  • Rating points-4
d
  • dsfs
  • April 26, 2024, 4:35 a.m.

C++ - Test 001. The first program and data types

  • Result:73points,
  • Rating points1
Last comments
k
kmssrFeb. 8, 2024, 6:43 p.m.
Qt Linux - Lesson 001. Autorun Qt application under Linux как сделать автозапуск для флэтпака, который не даёт создавать файлы в ~/.config - вот это вопрос ))
Qt WinAPI - Lesson 007. Working with ICMP Ping in Qt Без строки #include <QRegularExpressionValidator> в заголовочном файле не работает валидатор.
EVA
EVADec. 25, 2023, 10:30 a.m.
Boost - static linking in CMake project under Windows Ошибка LNK1104 часто возникает, когда компоновщик не может найти или открыть файл библиотеки. В вашем случае, это файл libboost_locale-vc142-mt-gd-x64-1_74.lib из библиотеки Boost для C+…
J
JonnyJoDec. 25, 2023, 8:38 a.m.
Boost - static linking in CMake project under Windows Сделал всё по-как у вас, но выдаёт ошибку [build] LINK : fatal error LNK1104: не удается открыть файл "libboost_locale-vc142-mt-gd-x64-1_74.lib" Хоть убей, не могу понять в чём дел…
G
GvozdikDec. 18, 2023, 9:01 p.m.
Qt/C++ - Lesson 056. Connecting the Boost library in Qt for MinGW and MSVC compilers Для решения твой проблемы добавь в файл .pro строчку "LIBS += -lws2_32" она решит проблему , лично мне помогло.
Now discuss on the forum
G
GarApril 22, 2024, 5:46 a.m.
Clipboard Как скопировать окно целиком в clipb?
DA
Dr Gangil AcademicsApril 20, 2024, 7:45 a.m.
Unlock Your Aesthetic Potential: Explore MSC in Facial Aesthetics and Cosmetology in India Embark on a transformative journey with an msc in facial aesthetics and cosmetology in india . Delve into the intricate world of beauty and rejuvenation, guided by expert faculty and …
a
a_vlasovApril 14, 2024, 6:41 a.m.
Мобильное приложение на C++Qt и бэкенд к нему на Django Rest Framework Евгений, добрый день! Такой вопрос. Верно ли следующее утверждение: Любое Android-приложение, написанное на Java/Kotlin чисто теоретически (пусть и с большими трудностями) можно написать и на C+…
Павел Дорофеев
Павел ДорофеевApril 14, 2024, 2:35 a.m.
QTableWidget с 2 заголовками Вот тут есть кастомный QTableView с многорядностью проект поддерживается, обращайтесь
f
fastrexApril 4, 2024, 4:47 a.m.
Вернуть старое поведение QComboBox, не менять индекс при resetModel Добрый день! У нас много проектов в которых используется QComboBox, в версии 5.5.1, когда модель испускает сигнал resetModel, currentIndex не менялся. В версии 5.15 при resetModel происходит try…

Follow us in social networks