State Design Pattern Real-time Example

State Design Pattern Real-time Example – Vending Machine

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

Vending Machine:

The Vending machine is one of the best real-time examples of the State Design Pattern. For example, you want to buy one product (Let say Pepsi) from the vending machine. Then what you have to do is, you have to select the product which is nothing but Pepsi and then you have to insert the money. Once you did that, then the vending machine will dispense the product. This is how the Vending machine works in real-time.

Please have a look at the following diagram. Let us assume that the internal state of the Vending machine is Money Not Inserted and Product Not Selected. Then what are all the operations you can perform on the Vending Machine? You can select the product and insert the money but you cannot get the product from the vending machine.

Once you select the product and insert the money the state of the Vending machine changed from Money Not Inserted and Product Not Selected to Money Inserted and Product Selected State. Once the state change to Money Inserted and Product Selected, then what the Vending will do is, it will give you the product as well as the balance amount if any.

State Design Pattern Real-time Example - Vending Machine

This is how the Vending Machine works and based on the internal state the behavior of the vending machine will change.

Implementation of Vending Machine using State Design Pattern in C#:

Step1: Creating the State Interface

Create an interface with the IVendingMachineState.cs and then copy and paste the following code in it. Here we created the interface with two methods i.e. SelectProductAndInsertMoney and DispenseProduct.

using System;
namespace StatePattern
{
    public interface IVendingMachineState
    {
         void SelectProductAndInsertMoney(int amount, String productName);
         void DispenseProduct();
    }
}
Step2: Creating the Concrete States

The Vending machine has basically two internal states i.e. NoMoneyState and HasMoneyState. So, we need to create two concrete state classes by implementing the IVendingMachineState interface.

NoMoneyState:

Create a class file with the name NoMoneyState.cs and then copy and paste the following code in it. Here, we implement IVendingMachineState interface methods.

using System;
namespace StatePattern
{
    public class NoMoneyState : IVendingMachineState
    {
        public void DispenseProduct()
        {
            Console.WriteLine("Vending Machine cannot dispense product because money is not inserted and product is not selected");
        }

        public void SelectProductAndInsertMoney(int amount, string productName)
        {
            Console.WriteLine(amount + "Rs has been inserted and " + productName + " has been selected");
        }
    }
}
HasMoneyState

Create a class file with the name HasMoneyState.cs and then copy and paste the following code in it. This class also implements the IVendingMachineState interface and provide the implementation for the two methods.

using System;
namespace StatePattern
{
    public class HasMoneyState : IVendingMachineState
    {
        public void DispenseProduct()
        {
            Console.WriteLine("Vending Machine  dispensed the product ");
        }

        public void SelectProductAndInsertMoney(int amount, string productName)
        {
            Console.WriteLine("Already Vending machine has money and product selected, So wait till it finish the current dispensing process");
        }
    }
}
Step3: Creating the Context object

Create a class with the name VendingMachine and then copy and paste the following code in it. The following is self-explained so please go through the comment lines.

using System;
namespace StatePattern
{
    public class VendingMachine : IVendingMachineState
    {
        //Createing a variable to maintain the internal state
        public IVendingMachineState vendingMachineState { get; set; }

        //Initially the vending machine has NoMoneyState
        public VendingMachine()
        {
            vendingMachineState = new NoMoneyState();
        }
        
        public void SelectProductAndInsertMoney(int amount, string productName)
        {
            vendingMachineState.SelectProductAndInsertMoney(amount, productName);
            // Money has been inserted so vending Machine internal state 
            // changed to 'hasMoneyState'

            if (vendingMachineState is NoMoneyState)
            {
                vendingMachineState = new HasMoneyState();
                Console.WriteLine("VendingMachine internal state has been moved to : "
                                + vendingMachineState.GetType().Name);
            }
        }

        public void DispenseProduct()
        {
            vendingMachineState.DispenseProduct();
            // Product has been dispensed so vending Machine changed the
            // internal state to 'NoMoneyState'

            if (vendingMachineState is HasMoneyState)
            {
                vendingMachineState = new NoMoneyState();
                Console.WriteLine("VendingMachine internal state has been moved to : "
                                + vendingMachineState.GetType().Name);
            }
        }
    }
}
Step4: Client

Modify the Main method as shown below.

using System;
namespace StatePattern
{
    class Program
    {
        static void Main(string[] args)
        {
            // Initially Vending Machine will be 'noMoneyState'
            VendingMachine vendingMachine = new VendingMachine();

            Console.WriteLine("Current VendingMachine State : "
                            + vendingMachine.vendingMachineState.GetType().Name + "\n");

            vendingMachine.DispenseProduct();
            vendingMachine.SelectProductAndInsertMoney(50, "Pepsi");

            // Money has been inserted so vending Machine internal state
            // changed to 'hasMoneyState'
            Console.WriteLine("\nCurrent VendingMachine State : "
                            + vendingMachine.vendingMachineState.GetType().Name + "\n");

            vendingMachine.SelectProductAndInsertMoney(50, "Fanta");
            vendingMachine.DispenseProduct();

            // Product has been dispensed so vending Machine internal state
            // changed to 'NoMoneyState'
            Console.WriteLine("\nCurrent VendingMachine State : "
                            + vendingMachine.vendingMachineState.GetType().Name);

            Console.Read();
        }
    }
}

Output:

Real-time Example of State Design Pattern in C#

The task for You:

This real-time example is a task for you guys. I will explain the concept with the diagram and I expect you guys to do the program implementation and provide your code in the comment section.

Real-Time Example: TV Remote

TV Remote control is one of the best examples of the State Design Pattern. Using the TV Remote Control we can switch On the TV and switch off the TV. That means the Remote control internally maintains two states (i.e. On and Off).

For example, when the internal state is On it will on the TV as shown below.

Vending Machine Implementation using the State Design Pattern in C#

Similarly, when the state is Off it will off the TV as shown below.

Implementation of TV Remote Control using State Design Pattern in C#

In the next article, I am going to discuss the Template Design Pattern in C# with real-time examples. Here, in this article, I try to explain the Vending Machine Implementation using the State Design Pattern in C# with an example. I hope you enjoy this article.

Leave a Reply

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