BlackWaspTM
Design Patterns
.NET 1.1+

Decorator Design Pattern (2)

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.

Example Decorator

Earlier in this article I described an example use of the decorator pattern for a track-day hire system. In the remainder of the article we will implement the skeleton of such an object model. In the example we will define a vehicle class that holds details of a car, its hire charge and number of laps permitted. We will also create two decorator classes. The first decorator will be used to describe special offers by modifying the lap count and price. The second will add the method required to log the details of a hire period. We will then demonstrate the effects of the two wrappers.

The code involved in creating the entire functionality for this object model would be rather large so it will be limited to outputting messages to the console describing the state and behaviour of the objects. The code for the base classes and a concrete vehicle class is as follows. Note that C# 3.0 automatically implemented properties syntax has been used for brevity. For earlier versions of the language you will need to implement the properties and backing variables in full:

public abstract class VehicleBase
{
    public abstract string Make { get; }
    public abstract string Model { get; }
    public abstract double HirePrice { get; }
    public abstract int HireLaps { get; }
}


public class Ferrari360 : VehicleBase
{
    public override string Make
    {
        get { return "Ferrari"; }
    }

    public override string Model
    {
        get { return "360"; }
    }

    public override double HirePrice
    {
        get { return 100; }
    }

    public override int HireLaps
    {
        get { return 10; }
    }
}


public abstract class VehicleDecoratorBase : VehicleBase
{
    private VehicleBase _vehicle;

    public VehicleDecoratorBase(VehicleBase vehicle)
    {
        _vehicle = vehicle;
    }

    public override string Make
    {
        get { return _vehicle.Make; }
    }

    public override string Model
    {
        get { return _vehicle.Model; }
    }

    public override double HirePrice
    {
        get { return _vehicle.HirePrice; }
    }

    public override int HireLaps
    {
        get { return _vehicle.HireLaps; }
    }
}
15 February 2009