Using the Decorator design pattern to extend your classes behavior
“Favor object composition over class inheritance” is one of many software design principles out there . I won’t explain the meaning of the principle in this post, rather I would like to show you one of the ways it can be achieved. For a profound explanation of the principle I suggest you Google it or read about it here, here and here.
The hypothetical car factory example
At this point in time the car factory we’re working on sells two types of cars: the “Sport blaster 2000″ and the “City cruiser 2000″. The class diagram is as follows:

And the classes look like this:
public abstract class Car
{
public abstract string Name { get; set; }
public abstract string GetOptions();
}
public class SportCar: Car
{
private string name = "Sport blaster 2000";
public override string Name
{
get{ return name;}
set{ name = value;}
}
public override string GetOptions()
{
return string.Empty;
}
}
public class CityCar: Car
{
private string name = "City cruiser 2000";
public override string Name
{
get {return name; }
set{name = value;}
}
public override string GetOptions()
{
return string.Empty;
}
}
As you can see the Car class has a method “GetOptions” that will return the options for a specific car instance. For starters we want a gps, cruise control and tv option. We also want to keep in mind that in the future new options can be added and others could be removed.
Solution #1
Let’s add a boolean for each option to our base class and give the “GetOptions” method a base implementation. It would look something like this:
public abstract class Car
{
public abstract string Name { get; set; }
public bool Gps{get;set;}
public bool Tv{get;set;}
public bool CruiseControl{get;set;}
public virtual string GetOptions()
{
var options = string.Empty;
if(Gps)options += "Gps, ";
if(Tv)options += "Tv, ";
if(CruiseControl)options += "Cruise control, ";
return options;
}
}
The problem with this approach is that it will quickly become unmaintainable. Every time a new option becomes available or one gets removed we will have to change our Car base class and every subclass that uses these options, this could also have an effect on the consumers of those classes. Also what if we want to add multiple tv’s to one Car? Or what if a Tv can’t be added to all our models than we would have to implement some custom logic in those subclasses. Because the “GetOptions” method is implemented in the Car class, changing this method will have an impact on its subclasses, this change could potentially have unwanted effects for one of those subclasses.
Solution #2
Create a subclass for every possible combination. I’m not going to build this example but by applying some simple math (2^3 *2) you’ll find out that this approach would need 16 classes already, just for the current situation, a real class explosion. Again a maintenance nightmare.
What we would really like is have the ability to extend the Car class (adding new options) without having to touch the Car class itself. I have a feeling that Solution 3 will give us the answer we are searching for.
Solution #3
Meet the Decorator pattern. For a profound theoretical explanation of this pattern look here and here. In a nutshell a decorator extends a class its functionality by wrapping an instance of that class in it and overriding its behavior. Let’s look at our car decorator base class.
public abstract class CarDecorator: Car
{
protected readonly Car car;
protected CarDecorator(Car car)
{
this.car = car;
}
public override string Name
{
get {return car.Name; }
set {car.Name = value;}
}
}
Two things to point out here.
First: the CarDecorator inherits Car, meaning that it will behave as a Car. If you stick, and actually you should, to the design principle that states that you should always program against an interface (an abstract class or a .Net interface) instead of a concrete implementation you will be able to switch an implementation of a Car by an implementation of a CarDecorator without your consumers noticing it.
Secondly: the CarDecorator receives an instance of a car in its constructor (this could be a SportCar or a CityCar or even another CarDecorator) and uses it to implements its Name property.
Next we are going to implement our concrete CarDecorators.
public class GpsDecorator: CarDecorator
{
public GpsDecorator(Car car):base(car)
{
}
public override string GetOptions()
{
return car.GetOptions() + "Gps, ";
}
}
public class TvDecorator: CarDecorator
{
public TvDecorator(Car car)
: base(car)
{
}
public override string GetOptions()
{
return car.GetOptions() + "Tv, ";
}
}
Both decorators overwrite the “GetOptions” method by first calling the “car.GetOptions” method and then adding their own option.
Let’s see at the result of our little test application.
class Program
{
static void Main(string[] args)
{
Car sportCar = new SportCar();
Car cityCar = new CityCar();
Console.WriteLine("Cars with no decorations\n");
Console.WriteLine("Sport car options: "+ sportCar.GetOptions() + "\n");
Console.WriteLine("City car options: " + cityCar.GetOptions() + "\n");
sportCar = new CruiseControlDecorator(sportCar);
cityCar = new TvDecorator(new GpsDecorator(cityCar));
Console.WriteLine("\n\nCars with decorations\n");
Console.WriteLine("Sport car options: " + sportCar.GetOptions() + "\n");
Console.WriteLine("City car options: " + cityCar.GetOptions() + "\n");
Console.ReadLine();
}
}
And when we run this:
The class diagram now looks like this:
Summary
I was able to add functionality to my car implementations without touching those classes and even better, the consumers of my car classes wouldn’t even notice because they are still programming against an instance of Car. In the future when options are added or removed this will have no impact on my Car classes themselves which is a big advantage regarding to maintenance and testing.
I hope I was able to convince you guys that instead of creating large inheritance trees or extending base classes to the limit the Decorator pattern is a nice alternative to be considered next time you face a similar problem.

