Explanation of Decorator Design Pattern
Hello everyone, in this article we are going to talk about Decorator Design Pattern which is within Structural Design Patterns and we will built an example about it. We will use C# and visual studio for this example.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.
Comments