- Behavioral pattern
- The intent of this pattern is to allow an object to alter its behavior when its internal state changes. The object will appear to change its class.
- Context:- defines the interface thats of interest to its clients. It maintains an instance of a ConcreteState subclass that defines the current state.
- ConcreteState:- implements behavior associated with a state of the Context
- State:- defines an interface for encapuslating the behavior asociated with a particular state of the context.

namespace StatePattern
{
public abstract class BankAccountState
{
public BankAccount BankAccount { get; protected set; } = null!;
public decimal Balance { get; protected set; }
public abstract void Deposit(decimal amount);
public abstract void Withdraw(decimal amount);
}
public class NormalState : BankAccountState
{
public NormalState(decimal balance, BankAccount bankAccount)
{
Balance = balance;
BankAccount = bankAccount;
}
public override void Deposit(decimal amount)
{
Console.WriteLine($"--> {GetType()} , depositing {amount}");
Balance += amount;
}
public override void Withdraw(decimal amount)
{
Console.WriteLine($"--> {GetType()} , withdrawing {amount} from {Balance}");
Balance -= amount;
if (Balance < 0)
{
BankAccount.BankAccountState = new NegativeBalanceState(Balance, BankAccount);
}
}
}
public class NegativeBalanceState : BankAccountState
{
public NegativeBalanceState(decimal balance, BankAccount bankAccount)
{
Balance = balance;
BankAccount = bankAccount;
}
public override void Deposit(decimal amount)
{
Console.WriteLine($"--> {GetType()}, depositing {amount}");
Balance += amount;
if (Balance >= 0)
{
BankAccount.BankAccountState = new NormalState(Balance, BankAccount);
}
}
public override void Withdraw(decimal amount)
{
Console.WriteLine($"--> {GetType()}, cannot withdraw, balance {Balance}");
}
}
public class BankAccount
{
public BankAccountState BankAccountState { get; set; }
public BankAccount()
{
BankAccountState = new NormalState(200, this);
}
public void DepositAmount(decimal amount)
{
BankAccountState.Deposit(amount);
}
public void WithdrawAmount(decimal amount)
{
BankAccountState.Withdraw(amount);
}
}
}
PROGRAM.CS
using StatePattern;
BankAccount bankAccount = new();
bankAccount.DepositAmount(200);
bankAccount.WithdrawAmount(700);
bankAccount.WithdrawAmount(100);
OUTPUT
–> StatePattern.NormalState , depositing 200
–> StatePattern.NormalState , withdrawing 700 from 400
–> StatePattern.NegativeBalanceState, cannot withdraw, balance -300
GITHUB