State Pattern

  • 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);
        }
    }
}

				
			
				
					

using StatePattern;

BankAccount bankAccount = new();
bankAccount.DepositAmount(200);
bankAccount.WithdrawAmount(700);
bankAccount.WithdrawAmount(100);


				
			

–> StatePattern.NormalState , depositing 200
–> StatePattern.NormalState , withdrawing 700 from 400
–> StatePattern.NegativeBalanceState, cannot withdraw, balance -300

Leave a Comment