Decorator Pattern

GoF Definition

Attach additional responsibilities to an object dynamically.

Decorators provide a flexible alternative to subclassing for extending functionality.

This pattern promotes Open/Closed principal of SOLID principles. Class should be closed for modification but open for extension.

Using this design pattern, we can add a functionality without disturbing the existing functionalities. Very important to point to note is: This concept is useful when you want to add some special functionality to a specific object instead of the whole class. The decorator pattern allows you to dynamically attach additional functionality.

For understanding, let's take an example wherein a goverment office has a application to create documents. Assume that it the application where user can go and type the contents on a rich textbox and on saving, it creates all text into a pdf document with all the company headers and footers and saves it on a secured drive. So inside the hood think it as simple as an object with contents (bytes) with content type "application/pdf " is created and saved to drive.

But now there is a requirement to mark some of the documents with markings such as "Top Secret" or "Confidential".

Here decorator patterns comes in handy.

1. The IComponent interface defines one method— Operation() .

2. The Component class is the concrete implementation of IComponent

As you can see this is very general implementation of any program. There are no functionalities added on the fly and no decorators.

Now, lets implement decorators as shown below by extending above design.

1. The IComponent interface defines one method— Operation() .

2. The Component class is the concrete implementation of IComponent

3. DecoratorBase class (Abstract class) is introduced. DecoratorBase implements IComponent.

4. DecoratorBase can be inherited to create multiple concrete decorations— Decorator1 and Decorator2 .

5. The concrete decorators will override the IComponent implementation of the DecoratorBase and add a specific functionality.

6. DecoratorBase holds instance of IComponent. So, Decorator1 and Decorator2 are actually decorating this object instance.

From the client side,

IComponent document = new Component();

Decorator1 confidentialWaterMark = new Decorator1(document);

var resultDocument = confidentialWaterMark.Operation();

The client will have an object of the Component class and can call the Operation() method on it to get regular unmarked document.

The client can pass the same object through any of the decorators and call Operation() of the decorators to have the document marked (decorated)