C# - Decorator Design Pattern

 

Decorator Design pattern is one of the Structural pattern in the Gang Of Four Design Pattern. Decorator Pattern is very useful whenever we want to attach the new functionality to existing object. For example we have some class with some functionality and dynamically based on some condition we may want to add some other extra functionality. In this type of situation Decorator Design Pattern is very useful.

 

Today we discuss about Decorator Design Pattern in C# with Car example. For example you have some Car class which takes Car name and  will give Price. But in some special occasions you may have some offer. In this situation we require to change the base Car class to provides Price with discount, but it is violation of Design Pattern rules. So we have to add the discounts details to Car object by decorating the existing Car object.

 

The main components of Decorator Patter are one interface, one base class which implements the interface, one Decorator class which also implements the interface and will take basic Car object.

 

Interface - ICar

Basic Class - Car.cs which implements interface ICar

Decorator Class - DecoratorCar which implements ICar and takes basic class object

 

Let's implement Decorator Design Pattern in C# by using above components.

 

Open Microsoft Visual Studio => Create Console Application with name as DecoratorDesignPattern.

 

First Create interface ICar as shown below.

 

namespace DecoratorDesignPattern

{

    interface ICar

    {

        string Name { get; }

        double Price { get; }

    }

}

 

Then create basic Car class which implements above interface and takes Name as input parameter while creating the object for it as shown below.

 

namespace DecoratorDesignPattern

{

    class Car : ICar

    {

        string sName;

 

        public Car(string sName)

        {

            this.sName = sName;

        }

 

        #region ICar Members

 

        public string Name

        {

            get { return sName; }

        }

 

        public double Price

        {

            get { return 1000000; }

        }

 

        #endregion

    }

}

 

Now let's create actual decorator class which implements interface ICar and takes Car object as input for its constructor as shown below.

 

namespace DecoratorDesignPattern

{

    class DecoratorCar : ICar

    {

        ICar iCar;

        public DecoratorCar(ICar iCar)

        {

            this.iCar = iCar;

        }

 

        #region ICar Members

 

        public string Name

        {

            get { return iCar.Name + " - 25% Offer"; }

        }

 

        public double Price

        {

            get { return iCar.Price * (1 - 0.25); }

        }

 

        #endregion

    }

}

 

As shown above we create all required objects for Decorator Design Pattern and now test the design pattern by calling from client side as shown below.

 

using System;

 

namespace DecoratorDesignPattern

{

    class Program

    {

        static void Main(string[] args)

        {

            Car objCar = new Car("FordFiesta");

 

            Console.WriteLine("Car Name: " + objCar.Name + " ; Original Price: " + objCar.Price);

 

            DecoratorCar objDecorator = new DecoratorCar(objCar);

 

            Console.WriteLine("After Decoration - Car Name: " + objDecorator.Name + " ; Offer Price: " + objDecorator.Price);

            Console.ReadLine();

        }

    }

}

 

As explained first we are displaying original car price and then displaying price with discount after decorating the original Car object. Run the application and the output is as shown below.

 

 

In this way Decorator Design Pattern is very useful to provides the extra functionality to existing class without making any changes to it by decorating the existing class object.

                                                                                                                 

                                                                                                 DecoratorDesignPattern.zip (27.04 kb)