also Known as wrapper
- structural pattern.
- allows a user to add new functionality to an existing object without altering (Changing) its structure.
![]() |
![]() |
- Definitions
- What problems can it solve
- What solution does it describe
- Examples
- TO DO
- Summery
- Sources
-
-
is a structural Design pattern
-
allows a user to add new functionality to an existing object without altering (Changing) its structure.
-
acts as a wrapper to existing class.
-
This pattern creates a decorator class which:
- wraps the original class
- provides additional functionality keeping class methods signature intact.
-
-
- is a design Structural pattern
- that
allows behavior to be added to an individual object
, dynamically, without affecting the behavior of other objects from the same class. - The decorator pattern is often useful for adhering to the Single Responsibility Principle,
- as it allows functionality to be divided between classes with unique areas of concern.
- Decorator use can be more efficient than subclassing,
- because an object's behavior can be augmented without defining an entirely new object.
- Responsibilities should be added to (and removed from) an object dynamically at run-time.
- A flexible alternative (Changing) to subclassing for extending functionality should be provided.
- When using subclassing, different subclasses extend a class in different ways.
But an extension is bound (restricted) to the class at compile-time and can't be changed at run-time.
- implement the interface of the extended (decorated) object (Component) transparently by forwarding all requests to it perform additional functionality before/after forwarding a request.
- This allows working with different Decorator objects to extend the functionality of an object dynamically at run-time.
See also the UML class and sequence diagram below.
in this example we will decorate a shape with some color without alter (Change) shape class.
- Example in dart: click here
- Example Source: https://www.tutorialspoint.com/design_pattern/decorator_pattern.htm
- We're going to create a Shape interface and concrete classes implementing the Shape interface.
- We will then create an abstract decorator class ShapeDecorator implementing the Shape interface and having Shape object as its instance variable.
- RedShapeDecorator is concrete class implementing ShapeDecorator.
- DecoratorPatternDemo, our demo class will use RedShapeDecorator to decorate Shape objects.
- UML
- code
- Create an interface.
abstract class IShape {
void draw();
}
- Create concrete classes implementing the same interface.
class Rectangle implements IShape {
@override
void draw() => print("Shape: Rectangle");
}
class Circle implements IShape {
@override
void draw() => print("Shape: Circle");
}
- Create abstract decorator class implementing the Shape interface.
abstract class ShapeDecorator implements IShape {
IShape decoratedShape;
ShapeDecorator(IShape decoratedShape) : this.decoratedShape = decoratedShape;
@override
void draw() => decoratedShape.draw();
}
- Create concrete decorator class extending the ShapeDecorator class.
class RedShapeDecorator extends ShapeDecorator {
RedShapeDecorator(IShape decoratedShape) : super(decoratedShape);
@override
void draw() {
decoratedShape.draw();
_setRedBorder(decoratedShape);
}
void _setRedBorder(IShape decoratedShape) {
print("Border Color: Red");
}
}
- Use the main() to decorate Shape objects.
void main(List<String> args) {
IShape circle = Circle();
IShape redCircle = RedShapeDecorator(Circle());
IShape redRectangle = RedShapeDecorator(Rectangle());
print("Circle with normal border");
circle.draw();
print("\nCircle of red border");
redCircle.draw();
print("\nRectangle of red border");
redRectangle.draw();
}
- Example in dart: click here
- Example Source: https://en.wikipedia.org/wiki/Decorator_pattern#Java
- Wikipedia First example (window/scrolling scenario)
- The following example illustrates the use of decorators
- using the window/scrolling scenario.
- UML
- code
- The Window interface class
abstract class IWindow {
void draw(); // Draws the Window
String get getDescription; // returns a description of the Window
}
- Implementation of a simple Window without any scrollbars
class SimpleWindow implements IWindow {
@override
void draw() => print("This is SimpleWindow Class Draw"); // Draw window
@override
String get getDescription => "simple window Description";
}
- The decorator interface class
- abstract decorator class - note that it implements Window
abstract class WindowDecorator implements IWindow {
final IWindow _windowToBeDecorated; // the Window being decorated
WindowDecorator(IWindow windowToBeDecorated)
: _windowToBeDecorated = windowToBeDecorated;
@override
void draw() => _windowToBeDecorated.draw(); //Delegation
@override
String get getDescription => _windowToBeDecorated.getDescription; //Delegation
}
- The following classes contain the decorators for all Window classes,
- The first concrete decorator which adds vertical scrollbar functionality
class VerticalScrollBarDecorator extends WindowDecorator {
VerticalScrollBarDecorator(IWindow windowToBeDecorated)
: super(windowToBeDecorated);
@override
void draw() {
super.draw();
_drawVerticalScrollBar();
}
@override
String get getDescription =>
super.getDescription + ", including vertical scrollbars";
// new functionality >> Draw the vertical scrollbar
void _drawVerticalScrollBar() =>
print("add >> vertical scrollbar functionality");
}
- The second concrete decorator which adds horizontal scrollbar functionality
class HorizontalScrollBarDecorator extends WindowDecorator {
HorizontalScrollBarDecorator(IWindow windowToBeDecorated)
: super(windowToBeDecorated);
@override
void draw() {
super.draw();
_drawHorizontalScrollBar();
}
@override
String get getDescription =>
super.getDescription + ", including horizontal scrollbars";
void _drawHorizontalScrollBar() =>
print("add >> horizontal scrollbar functionality");
}
- Here's a test program that creates a Window instance which is fully decorated
- (i.e., with vertical and horizontal scrollbars), and prints its description:
void main(List<String> args) {
// Create a decorated Window with horizontal and vertical scrollbars
IWindow simpleWindowWithoutScrolling = SimpleWindow();
IWindow decoratedWindow = HorizontalScrollBarDecorator(
VerticalScrollBarDecorator(simpleWindowWithoutScrolling));
// Print the Window's description
print(decoratedWindow.getDescription);
}
// The output of this program is
// "simple window Description, including vertical scrollbars, including horizontal scrollbars".
// Notice how the getDescription method of the two decorators
// first retrieve the decorated Window's description
// and decorates it with a suffix.
- Example in dart: click here
- Example in dart: click here
- Example Source: https://github.com/scottt2/design-patterns-in-dart/tree/master/decorator
https://refactoring.guru/design-patterns/decorator
- instead of types
- we use decorators only add functionality
- (one implementation)
- instead of massive inheritance tree
- it is just take the main object (notifer and add a functionality to it)