Explanation of Decorator Design Pattern

Now let's begin.
First What is Decorator Design Pattern?
Decorator Design Patter is a Structural Design Pattern that will add specifications dynamically to the components and objects without deriving from related class. ıt is a flexible way to adding responsibilities to the components.
Now I want to share an example:
I want you to think an aircraft and the buyer can request some additional specifications and according to requested additional parts the cost will increase.
Below you will my example:
First we will create an interface to derive all of components and decorators here. We will use some same codes in these classes.
IAircraft.cs
namespace DecoratorPattern_Example
{
interface IAircraft
{
void apply_decoration(Aircraft _ac, string decorationType, bool hasOrNot);
}
}
And then I will create my decorator classes. Here I will send the component what I will decorate. Also when I try to apply any decoration in the target component, I want to specify the decoration type.
DecorateSeats .cs
using System;
namespace DecoratorPattern_Example
{
class DecorateSeats : IAircraft
{
private bool hasExtendenSeats = false;
public bool hasDecoration
{
get { return hasExtendenSeats; }
set { hasExtendenSeats = value; }
}
public void apply_decoration(Aircraft _ac, string decorationType, bool hasOrNot)
{
this.hasExtendenSeats = hasOrNot;
_ac.apply_decoration(_ac, decorationType, hasOrNot);
Console.WriteLine("Seats decoration Applied Status : " + hasOrNot.ToString());
}
}
}
DecorateFuelTank .cs
using System;
namespace DecoratorPattern_Example
{
class DecorateFuelTank : IAircraft
{
private bool hasExtendenFuelTank = false;
public bool hasDecoration
{
get { return hasExtendenFuelTank; }
set { hasExtendenFuelTank = value; }
}
public void apply_decoration(Aircraft _ac, string decorationType, bool hasOrNot)
{
this.hasExtendenFuelTank = hasOrNot;
_ac.apply_decoration(_ac, decorationType, hasOrNot);
Console.WriteLine("FuelTank decoration Applied Status : " + hasOrNot.ToString());
}
}
}
Here is my component class. I will manage everything which related to component here. Also I will derive this class from the interface that I declared above to allow the external decorations from another classes which derived from same class.
Aircraft .cs
using System;
namespace DecoratorPattern_Example
{
class Aircraft : IAircraft
{
public string brand = "";
public string model = "";
public int price = 0;
public bool hasExtendedSeats = false;
public bool hasExtendedFuelTanks = false;
public Aircraft(string _brand, string _model, int _price)
{
this.brand = _brand;
this.model = _model;
this.price = _price;
}
public bool hasDecoration
{
get { return false; }
set { }
}
public void apply_decoration(Aircraft _ac, string decorationType, bool hasOrNot)
{
if (decorationType == "fueltank") this.hasExtendedFuelTanks = hasOrNot;
else if (decorationType == "seats") this.hasExtendedSeats = hasOrNot;
}
public void print_aircraft_information()
{
Console.WriteLine("#################################");
Console.WriteLine("Aircraft Brand : " + this.brand);
Console.WriteLine("Aircraft model : " + this.model);
Console.WriteLine("Aircraft price : " + this.price);
Console.WriteLine("Aircraft has Extended Seats : " + this.hasExtendedSeats.ToString());
Console.WriteLine("Aircraft has Extended FuelTanks : " + this.hasExtendedFuelTanks.ToString());
Console.WriteLine("#################################");
}
}
}
Lastly, I will declare the component and decorators first. Then ı will make some changes in the target component via my decorator classes. These decorator classes and the component are the same derivative class.
Program.cs
using System;
namespace DecoratorPattern_Example
{
class Program
{
static void Main(string[] args)
{
//First declare the Aircraft component
Aircraft _aircraft = new Aircraft("Boeing", "B777", 295000000);
//Then declare the decorator classes
DecorateFuelTank decorateFuelTank = new DecorateFuelTank();
DecorateSeats decorateSeats = new DecorateSeats();
//then decorate the status of aircraft and print
decorateFuelTank.apply_decoration(_aircraft, "fueltank", true);
decorateSeats.apply_decoration(_aircraft, "seats", false);
_aircraft.print_aircraft_information();
Console.WriteLine("---------------------------------------");
//redecorate it again and print again
decorateFuelTank.apply_decoration(_aircraft, "fueltank", false);
decorateSeats.apply_decoration(_aircraft, "seats", true);
_aircraft.print_aircraft_information();
Console.ReadLine();
}
}
}
Output:
FuelTank decoration Applied Status : True
Seats decoration Applied Status : False
#################################
Aircraft Brand : Boeing
Aircraft model : B777
Aircraft price : 295000000
Aircraft has Extended Seats : False
Aircraft has Extended FuelTanks : True
#################################
---------------------------------------
FuelTank decoration Applied Status : False
Seats decoration Applied Status : True
#################################
Aircraft Brand : Boeing
Aircraft model : B777
Aircraft price : 295000000
Aircraft has Extended Seats : True
Aircraft has Extended FuelTanks : False
#################################
I hope it is not complicated.
That is all in this article.
Have a good decorating your components.
Burak Hamdi TUFAN.