Decorator Design Pattern Real-Time Example

Decorator Design Pattern Real-Time Example – Pizza

In this article, I am going to discuss the Decorator Design Pattern Real-Time Example – Pizza in C#. Please read our previous article where we discussed the Decorator Design Pattern in C# with examples.

As we already discussed in our previous article, the decorator design pattern is used to add new functionalities to an existing object at run time without modifying the structure of the existing objects. This is the reason why it belongs to the structural design pattern category. With this keep in mind let us try to understand the real-time example of Pizza using the decorator design pattern.

Decorator Design Pattern Real-Time Example – Pizza

Suppose you want to prepare either chicken pizza or vegetable pizza. Then what you need to do is, first you need to prepare the plain pizza. Then what the Pizza Decorator will do is, it will add chicken to the plain pizza if you want chicken pizza or it will add vegetables to the plain pizza if you want vegetable pizza. So, you are getting chicken pizza or vegetable pizza by adding chicken or vegetable to the plain pizza by the Pizza decorator.

Decorator Design Pattern Real-Time Example – Pizza

So, as per the decorator design pattern, it will add additional functionalities or behaviors to an existing object. So, in this case, Plain pizza is the existing object and adding chicken or vegetable (based on the type of pizza you want) by pizza decorator is the additional functionality.

So, if you want vegetable pizza, then the pizza decorator will add vegetables to the plain pizza and return veg pizza. In the same way, if you want chicken pizza, then the pizza decorator will add chicken to the plain pizza and return chicken pizza. This is one of the best examples of Decorator Design Patter.

Class Diagram of the above Pizza Example:

Please have a look at the following image.

Class Diagram of the Decorator Design Pattern Realtime example pizza

At the top, you can see the Pizza interface and it has the MakePizza method. This interface is implemented by the PlainPizza concrete class provides the implementation for the MakePizza method. So, when you call the MakePizza method on the PlainPizza object it will return plain pizza to the caller.

The PizzaDecorator is an abstract class and it also implements the Pizza interface. It has Constructor and to the constructor, you need to pass the pizza object which you want to decorate.

The PizzaDecorator abstract class is extended two concrete classes i.e. ChickenPizzaDecorator and VegPizzaDecorator. Both this class overrides the MakePizza method. The ChickenPizzaDecorator will add chicken to the Plain Pizza and return chicken pizza to the caller. Similarly, the VegPizzaDecorator will add vegetables to the Plain Pizza and return Veg Pizza to the caller.

On the left-hand side, you can see the client and it has the main method. This method is used to extend the decorator design pattern.

Implementation of Pizza using Decorator Design pattern in C#:

Let us implement the above Decorator Design Pattern Real-Time Example – Pizza step by step using C#.

Step1: Creating the Pizza interface

This is going to be an interface. So, create an interface with the name Pizza and then copy and paste the following code in it. This Pizza interface has one abstract method i.e. MakePizza.

namespace DecoratorDesignPatternRealTimeExample
{
    public interface Pizza
    {
        string MakePizza();
    }
}
Step2: Creating Plain Pizza

This is going to be a concrete class. So, create a class file with the name PlainPizza and then copy and paste the following code in it. This class implements the Pizza interface and provide an implementation for the MakePizza method. What this MakePizza method will do is, it will simply return a Plain Pizza to the caller.

namespace DecoratorDesignPatternRealTimeExample
{
    public class PlainPizza : Pizza
    {
        public string MakePizza()
        {
            return "Plain Pizza";
        }
    }
}
Step3: Creating Pizza Decorator

This is going to be an abstract class. So, create a class with the name PizzaDecorator and then copy and paste the following code in it. This class also implements the Pizza interface and provides the implementation for the MakePizza method. We declare the MakePizza method as virtual and the reason for this is, it is going to be overridden by the child classes.

namespace DecoratorDesignPatternRealTimeExample
{
    public abstract class PizzaDecorator : Pizza
    {
        protected Pizza pizza;

        public PizzaDecorator(Pizza pizza)
        {
            this.pizza = pizza;
        }

        public virtual string MakePizza()
        {
           return pizza.MakePizza();
        }
    }
}
Step4: Creating Chicken Pizza Decorator

This is going to be a concrete class. So, create a class file with the name ChickenPizzaDecorator and then copy and paste the following code in it. This class is inherited from the PizzaDecorator abstract class and overrides the MakePizza method. What this MakePizza method will do is, it will add chicken to the plain pizza and will return the Chicken Pizza to the caller.

namespace DecoratorDesignPatternRealTimeExample
{
    public class ChickenPizzaDecorator : PizzaDecorator
    {
        public ChickenPizzaDecorator(Pizza pizza) : base(pizza)
        {
        }

        public override string MakePizza()
        {
            return pizza.MakePizza() + AddChicken();
        }

        private string AddChicken()
        {
            return ", Chicken added";
        }
    }
}
Step5: Creating Veg Pizza Decorator

This is also going to be a concrete class. So, create a class file with the name VegPizzaDecorator and then copy and paste the following code in it. This means it also inherited from the PizzaDecorator abstract class and also overrides the MakePizza method. The MakePizza method will add the Vegetables to the plain pizza and will return Veg Pizza to the caller.

namespace DecoratorDesignPatternRealTimeExample
{
    public class VegPizzaDecorator : PizzaDecorator
    {
        public VegPizzaDecorator(Pizza pizza) : base(pizza)
        {
        }

        public override string MakePizza()
        {
            return pizza.MakePizza() + AddVegetables();
        }

        private string AddVegetables()
        {
            return ", Vegetables added";
        }
    }
}
Step6: Client

Please modify the Main method as shown below. Here, first, we create an object of PlainPizza and then call the MakePizza method which will create and return plain pizza. Then we create the instance of ChickenPizzaDecorator and pass the Plain Pizza instance as a parameter to the constructor. And when we call the MakePizza method of the ChickenPizzaDecorator instance, it will add Chicken to the plain pizza and return chicken pizza. The same is in the case of VegPizzaDecorator.

using System;
namespace DecoratorDesignPatternRealTimeExample
{
    class Program
    {
        static void Main(string[] args)
        {
            PlainPizza plainPizzaObj = new PlainPizza();
            string plainPizza = plainPizzaObj.MakePizza();
            Console.WriteLine(plainPizza);

            PizzaDecorator chickenPizzaDecorator = new ChickenPizzaDecorator(plainPizzaObj);
            string chickenPizza = chickenPizzaDecorator.MakePizza();
            Console.WriteLine("\n'" + chickenPizza + "' using ChickenPizzaDecorator");

            VegPizzaDecorator vegPizzaDecorator = new VegPizzaDecorator(plainPizzaObj);
            string vegPizza = vegPizzaDecorator.MakePizza();
            Console.WriteLine("\n'" + vegPizza + "' using VegPizzaDecorator");

            Console.Read();
        }
    }
}

Output:

Implementation of Pizza using Decorator Design pattern in C#:

In the next article, I am going to discuss the Bridge Design Pattern in C# with some examples. Here, in this article, I try to explain the Decorator Design Pattern Real-Time Example – Pizza in C# step by step. I hope you understood the need and use of Facade Design Pattern in C#.

Leave a Reply

Your email address will not be published. Required fields are marked *