DEV Community

Juarez Júnior for Develop4Us

Posted on • Edited on

C# Design Pattern: State

The State pattern allows an object to change its behavior when its internal state changes. This makes the object appear to change its class. It's useful when you want an object to have different behaviors depending on its current state, such as a vending machine that can be in states like "waiting for coin," "dispensing item," or "out of stock."

C# Code Example:

// State interface
public interface IState
{
    void InsertCoin(VendingMachine machine);
    void SelectProduct(VendingMachine machine);
    void DispenseProduct(VendingMachine machine);
}

// State: Waiting for coin
public class WaitingForCoin : IState
{
    public void InsertCoin(VendingMachine machine)
    {
        Console.WriteLine("Coin inserted. Select a product.");
        machine.SetState(new WaitingForSelection());
    }

    public void SelectProduct(VendingMachine machine)
    {
        Console.WriteLine("Insert a coin first.");
    }

    public void DispenseProduct(VendingMachine machine)
    {
        Console.WriteLine("Insert a coin and select a product.");
    }
}

// State: Waiting for product selection
public class WaitingForSelection : IState
{
    public void InsertCoin(VendingMachine machine)
    {
        Console.WriteLine("You've already inserted a coin. Select a product.");
    }

    public void SelectProduct(VendingMachine machine)
    {
        Console.WriteLine("Product selected. Dispensing product...");
        machine.SetState(new ProductDispensed());
    }

    public void DispenseProduct(VendingMachine machine)
    {
        Console.WriteLine("Select a product first.");
    }
}

// State: Dispensing product
public class ProductDispensed : IState
{
    public void InsertCoin(VendingMachine machine)
    {
        Console.WriteLine("Please wait, we're dispensing your product.");
    }

    public void SelectProduct(VendingMachine machine)
    {
        Console.WriteLine("Please wait, the product is being dispensed.");
    }

    public void DispenseProduct(VendingMachine machine)
    {
        Console.WriteLine("Product dispensed! Please take your product.");
        machine.SetState(new WaitingForCoin());
    }
}

// Vending Machine class
public class VendingMachine
{
    private IState _currentState;

    public VendingMachine()
    {
        _currentState = new WaitingForCoin();
    }

    public void SetState(IState newState)
    {
        _currentState = newState;
    }

    public void InsertCoin()
    {
        _currentState.InsertCoin(this);
    }

    public void SelectProduct()
    {
        _currentState.SelectProduct(this);
    }

    public void DispenseProduct()
    {
        _currentState.DispenseProduct(this);
    }
}

class Program
{
    static void Main(string[] args)
    {
        VendingMachine machine = new VendingMachine();

        // Test the vending machine
        machine.InsertCoin();
        machine.SelectProduct();
        machine.DispenseProduct();
    }
}
Enter fullscreen mode Exit fullscreen mode

Code Explanation:
In this example, the VendingMachine class changes its behavior based on its current state. When a coin is inserted, the state changes from WaitingForCoin to WaitingForSelection. After the product is selected, the state changes to ProductDispensed. Each state defines specific behavior for actions like inserting a coin, selecting a product, or dispensing the product.

Conclusion:
The State pattern is useful when an object can have different behaviors depending on its internal state. It allows you to separate the logic related to each state, making the code easier to understand and modify.

Source code: GitHub

Top comments (0)