BlackWaspTM

This web site uses cookies. By using the site you accept the cookie policy.This message is for compliance with the UK ICO law.

Design Patterns
.NET 1.1+

Decorator Design Pattern

The decorator pattern is a design pattern that extends the functionality of individual objects by wrapping them with one or more decorator classes. These decorators can modify existing members and add new methods and properties at run-time.

What is the Decorator Pattern?

The decorator pattern is a Gang of Four design pattern. This is a structural pattern as it defines a manner for creating relationships between classes or entities. The decorator pattern is used to extend or alter the functionality of objects at run-time by wrapping them in an object of a decorator class. This provides a flexible alternative to using inheritance to modify behaviour.

The decorator pattern is used to extend the functionality of individual objects, not classes. This means that the modifications are made at run-time rather than at design time. This allows changes to be applied to objects in response to specific conditions such as user-selected options and business rules. It also means that several objects based upon the same underlying class can be decorated in different manners. In addition, as both the class of the object being modified and the class of the decorator share a base class, multiple decorators can be applied to the same object to incrementally modify behaviour.

An example of the decorator pattern could be used in a computer system used by a company that provides vehicles for hire during track days. Such a company could own a fleet of cars and motorcycles for hire. Each vehicle could be represented by an instance of a class that inherits from the Vehicle class. This would define key properties such as make, model, hire price and number of laps permitted.

Vehicles in the track day system will not be available for hire if they have faults. However, if no faults are known, the vehicle's object would be wrapped by the Hireable class. This class would be a decorator that holds a reference to the underlying vehicle and adds extra functionality to allow logging of the details of hire periods. Further decorators could be added according to business rules. For example, special offer decorators could be added to automatically reduce the hire price or increase the number of laps that may be driven.

Implementing the Decorator Pattern

Decorator Design Pattern UML

The UML class diagram above describes an implementation of the decorator design pattern. The items in the diagram are described below:

  • ComponentBase. This abstract class is the base class for both the concrete components and all decorator classes. The base class defines any standard members that will be implemented by these classes. If you do not wish to create any actual functionality in this class you may decide to create it as an interface instead.
  • ConcreteComponent. The ConcreteComponent class inherits form the ComponentBase class. There may be multiple concrete component classes, each defining a type of object that may be wrapped by the decorators.
  • DecoratorBase. This abstract class is the base class for all decorators for components. The class inherits its public interface from ComponentBase so that decorators can be used in place of concrete objects. It adds a constructor that accepts a ComponentBase object as its parameter. The passed object is the component that will be wrapped. As the wrapped object must inherit from ComponentBase, it may be a concrete component or another decorator. This allows for multiple decorators to be applied to a single object. When calls to the DecoratorBase's members are made, these are passed unmodified to the matching member of the wrapped object.
  • ConcreteDecorator. The ConcreteDecorator class provides a decorator for components. In the diagram, an additional method has been included in the decorator. The Operation member can be implemented in two manners. Firstly, the operation may be unchanged. In this case, the implementation simply calls the base method. Secondly, the underlying operation may be modified or replaced completely. In this case, new functionality will be added, which may or may not call the base method.

The following shows the basic code of the decorator design pattern implemented using C#.

public abstract class ComponentBase
{
    public abstract void Operation();
}


public class ConcreteComponent : ComponentBase
{
    public override void Operation()
    {
        Console.WriteLine("Component Operation");
    }
}


public abstract class DecoratorBase : ComponentBase
{
    private ComponentBase _component;

    public DecoratorBase(ComponentBase component)
    {
        _component = component;
    }

    public override void Operation()
    {
        _component.Operation();
    }
}


public class ConcreteDecorator : DecoratorBase
{
    public ConcreteDecorator(ComponentBase component) : base(component) { }

    public override void Operation()
    {
        base.Operation();
        Console.WriteLine("(modified)");
    }
}
15 February 2009