State design pattern is used to modify
behavior of an object whenever internal state changes. State Pattern falls
under behavioral pattern of GOF (Gang of Four) patterns.
When to use –
State pattern used when state of an object
changes based on some action or condition at run-time without changing the
interface. State pattern used to alter the behavior of an object as its
internal state changes. This pattern used for some complex decision making
program which represents multiple states.
Major components of State pattern –
Context – The
clients of the State design pattern use the context class directly. Clients do
not have access to state objects. Context class holds State objects that
changes behavior according to its state.
State – This
is an abstract class.
Concrete State – This class inherited from State class. This class provides real
functionality that used by Context object. This class provides behavior to
check and change state based on condition/action.
Let’s have a look on below example of State
design pattern.
Code –
//state
public abstract class State
{
public BankAccount Account { get; set; }
public double Balance { get; set; }
public abstract void Deposit(double amount);
public abstract void Withdraw(double amount);
}
//concrete state
public class Normal : State
{
public Normal(State state)
{
Balance = state.Balance;
Account = state.Account;
}
public Normal(double balance, BankAccount account)
{
Balance = balance;
Account = account;
}
public override void Deposit(double amount)
{
Balance += amount;
CheckState();
}
public override void Withdraw(double amount)
{
Balance -= amount;
CheckState();
}
void CheckState()
{
if (Balance > 1000)
Account.State = new Classic(this);
}
}
//concrete state
public class Classic : State
{
public Classic(State state)
{
Balance = state.Balance;
Account = state.Account;
}
public Classic(double balance, BankAccount account)
{
Balance = balance;
Account = account;
}
public override void Deposit(double amount)
{
Balance += amount;
CheckState();
}
public override void Withdraw(double amount)
{
Balance -= amount;
CheckState();
}
void CheckState()
{
if (Balance < 1000)
Account.State = new Normal(this);
else if (Balance
> 2000)
Account.State = new Platinum(this);
}
}
//concrete state
public class Platinum : State
{
public Platinum(State state)
{
Balance = state.Balance;
Account = state.Account;
}
public Platinum(double balance, BankAccount account)
{
Balance = balance;
Account = account;
}
public override void Deposit(double amount)
{
Balance += amount;
CheckState();
}
public override void Withdraw(double amount)
{
Balance -= amount;
CheckState();
}
void CheckState()
{
if (Balance < 2000)
Account.State = new Classic(this);
else if (Balance
< 1000)
Account.State = new Normal(this);
}
}
//context
public class BankAccount
{
public State State { get; set; }
public string Name { get; set; }
public BankAccount(string name)
{
Name = name;
State = new Normal(0, this);
}
public double Balance
{
get { return
State.Balance; }
}
public void Deposit(double amount)
{
State.Deposit(amount);
Console.WriteLine("Deposited -
{0}", amount);
Console.WriteLine("Balance - {0}", Balance);
Console.WriteLine("Account Status - {0}",
State.GetType().Name);
Console.WriteLine(new string('-', 50));
}
public void Withdraw(double amount)
{
State.Withdraw(amount);
Console.WriteLine("Withdrawn - {0}", amount);
Console.WriteLine("Balance - {0}", Balance);
Console.WriteLine("Account Status - {0}",
State.GetType().Name);
Console.WriteLine(new string('-', 50));
}
}
class Program
{
//entry point
static void Main(string[] args)
{
BankAccount account = new BankAccount("Mitesh
Sureja");
account.Deposit(500);
account.Deposit(600);
account.Deposit(1000);
account.Withdraw(500);
account.Withdraw(1500);
Console.Read();
}
}
Output –
Above example demonstrates change in bank account status based on its remaining balance. In this example, BankAccount class is context class and Normal, Classic, Platinum are various classes of concrete state. The CheckState method of concrete state classes responsible to check condition and change states accordingly on each action like Deposit or Withdraw. Based on available balance in bank account, the status automatically changes between Normal, Classic and Platinum.
You can download full code from Gist.
I hope this article helps you to know more
about State Design Pattern. Please leave your feedback in comments section
below.
References –
See Also –
Creational Patterns
|
Structural Patterns
|
Behavioral Patterns
|
|
||
|
|
|
|
|
|
|
|
|
|
|
No comments:
Post a Comment