Printed from www.rmfusion.com A Developer website designed for Developers

State Pattern Code Review

Code Download

Define the Pattern Interface and Handler Objects

Define the IState interface to be used as the "blueprint" for the main State classes.

interface IState { void Deposit(Context context, Double amount); Boolean Withdraw(Context context, Double amount); Boolean PayInterest(Context context); }

The RedState class (object) represents one particular state.

class RedState : IState { public void Deposit(Context context, double amount) { context.Balance += amount;
if (context.Balance > 0) { context.State = new SliverState(); } } public Boolean Withdraw(Context context, double amount) { context.Balance -= 15.00; Console.WriteLine("No funds available for withdrawal!\n"); return (false); } public Boolean PayInterest(Context context) { Console.WriteLine("No interest paid!\n"); return (false); } }

The SliverState class (object) represents another available state, and is able to update the State object as required.

class SliverState : IState { public void Deposit(Context context, double amount) { context.Balance += amount; UpdateState(context); } public Boolean Withdraw(Context context, double amount) { context.Balance -= amount; UpdateState(context); return (true); } public Boolean PayInterest(Context context) { Console.WriteLine("No interest paid!\n"); return (false); } private void UpdateState(Context context) { if (context.Balance < 0) { context.State = new RedState(); } else if (context.Balance > 1000) { context.State = new GoldState(); } } }

The GoldState class (object) represents another available state, and is able to update the State object as required.

class GoldState : IState { public void Deposit(Context context, double amount) { context.Balance += amount; UpdateState(context); } public Boolean Withdraw(Context context, double amount) { context.Balance -= amount; UpdateState(context); return (true); } public Boolean PayInterest(Context context) { context.Balance *= 1.05; UpdateState(context); return (true); } private void UpdateState(Context context) { if (context.Balance < 0) { context.State = new RedState(); } else if (context.Balance < 1000) { context.State = new SliverState(); } } }

Define the Context Object

The Context class (object) initialises the State object and invokes methods on the State class (object).

class Context { public IState State { get; set; } public Double Balance { get; set; }
private String m_owner;
public Context(String Owner) { this.m_owner = Owner; this.State = new SliverState(); }
public void Deposit(Double amount) { State.Deposit(this, amount); Console.WriteLine(String.Format("Deposited {0:C}", amount)); this.ShowBalance(); } public void Withdraw(Double amount) { if (State.Withdraw(this, amount)) { Console.WriteLine(String.Format("Withdrew {0:C}", amount)); } else { Console.WriteLine("\t15% charge applied"); } this.ShowBalance(); } public void PayInterest() { if (State.PayInterest(this)) { Console.WriteLine("Interested Paid"); this.ShowBalance(); } } private void ShowBalance() { Console.WriteLine(String.Format("\tBalance {0:C}", this.Balance)); Console.WriteLine(String.Format("\tStatus {0}\n", this.State.GetType().Name)); } }

Use the State Pattern

The Program class creates the Context object invokes methods on the Context class (object).

class Program { static void Main(string[] args) { Context context = new Context("Jim Johnson");
context.Deposit(500.00); context.PayInterest(); context.Deposit(300.00); context.Deposit(550.00); context.PayInterest(); context.Withdraw(2000.00); context.Withdraw(1100.00);
Console.Read(); } }