状态模式(State Pattern):
当一个对象的内在状态变化时允许改变其行为,这个对象看起来像是改变了其类。
状态模式主要解决的是当控制一个对象状态转换的条件过于复杂时的情况。把状态的判断逻辑移到表示
不同状态的一系列类当中,可以把复杂的判断逻辑简单化。
/// <summary>
/// 抽象状态类,定义一个接口以封装与Context的一个特定状态相关的行为
/// 包含Context类:引发状态变化的类
/// </summary>
abstract class State
{
public abstract void Handle(Context context);
}
/// <summary>
/// Context类:引发状态改变的类
/// 维护一个ConcreteState子类的实例,这个实例定义当前状态
/// </summary>
class Context
{
private State _state;
public State State
{
get { return _state; }
set { _state = value; }
}
public Context(State state)
{
this._state = state;
}
public void Request()
{
_state.Handle(this);
}
}
/// <summary>
/// 具体的状态类,每一个子类实现一个与Context的一个状态相关的行为
/// 往往设置下一个状态
/// </summary>
class ConcreteStateA:State
{
public override void Handle(Context context)
{
//设置下一个状态是B
context.State = new ConcreteStateB();
}
}
class ConcreteStateB : State
{
public override void Handle(Context context)
{
//设置下一个状态是A
context.State = new ConcreteStateA();
}
}
class Program
{
static void Main()
{
//设置初始状态为A
Context c = new Context(new ConcreteStateA());
//不断的请求,同时更改状态
c.Request();
c.Request();
c.Request();
}
}
应用:
1.对象的行为依赖于它的状态(属性)并且它必须可以根据它的状态而改变它的行为。
2.操作很多部分都带有与对象状态有关的大量条件语句。
状态模式在工作流或游戏等各种系统中大量使用。例如在政府OA系统中,一个公文的审批就包含很多状态:
未办、正在处理、正在办理、正在批示、正在审批和已经完成
实例:银行账户分类
允许账户因它的余额不同而有不同的分类,分为RedState(红色状态)、SilverState(银色状态)、GoldState(金色状态)
这些状态表示了账户是否透支、新账户、常务账户
/// <summary>
/// 抽象状态类
/// </summary>
public abstract class State
{
protected Account account;
//金额
protected double balance;
//利息
protected double interest;
//最低限额
protected double lowerLimit;
//最高限额
protected double upperLimit;
/// <summary>
/// 账户类属性
/// </summary>
public Account Account
{
get { return this.account; }
set { this.account = value; }
}
/// <summary>
/// 账户余额
/// </summary>
public double Balance
{
get { return this.balance; }
set { this.balance = value; }
}
/// <summary>
/// 初始化
/// </summary>
abstract public void Initialize();
/// <summary>
/// 存款
/// </summary>
/// <param name="amount"></param>
abstract public void Deposit(double amount);
/// <summary>
/// 取款
/// </summary>
/// <param name="amount"></param>
abstract public void WithDraw(double amount);
/// <summary>
/// 付利息
/// </summary>
abstract public void PayInterest();
/// <summary>
/// 状态变化
/// </summary>
abstract public void StateChangeCheck();
}
/// <summary>
/// 具体状态类
/// 红色状态:透支状态
/// </summary>
public class RedState:State
{
double serviceFee;
public RedState(State state)
{
this.balance = state.Balance;
this.account = state.Account;
Initialize();
}
public override void Initialize()
{
//透支状态没有利息,最低额度为负100,最高为0,手续费15
this.interest = 0.0;
this.lowerLimit = -100;
this.upperLimit = 0.0;
this.serviceFee = 15.00;
}
public override void Deposit(double amount)
{
this.balance += amount;
StateChangeCheck();
}
public override void WithDraw(double amount)
{
amount = amount - serviceFee;
Console.WriteLine("没有存款可供支取!");
}
public override void PayInterest()
{
Console.WriteLine("没有存款,银行不会支付利息!");
}
public override void StateChangeCheck()
{
//当有存款是,状态变为银色
if (this.balance > upperLimit)
{
account.State = new SilverState(this);
}
}
}
public class SilverState:State
{
public SilverState(State state)
{
this.balance = state.Balance;
this.account = state.Account;
Initialize();
}
public SilverState(double balance,Account account)
{
this.balance = balance;
this.account = account;
Initialize();
}
public override void Initialize()
{
this.interest = 0.0;
this.lowerLimit = 0.0;
this.upperLimit = 1000.00;
}
public override void Deposit(double amount)
{
this.balance += amount;
StateChangeCheck();
}
public override void WithDraw(double amount)
{
balance -= amount;
StateChangeCheck();
}
public override void PayInterest()
{
balance += interest * balance;
StateChangeCheck();
}
public override void StateChangeCheck()
{
//当存款小于0时转为RedState状态;当大于当前最大限额时,转为金色状态
if (balance < lowerLimit)
{
account.State = new RedState(this);
}
else if (balance > upperLimit)
{
account.State = new GoldState(this);
}
}
}
public class GoldState:State
{
public GoldState(State state)
{
this.balance = state.Balance;
this.account = state.Account;
Initialize();
}
public override void Initialize()
{
interest = 0.05;
lowerLimit = 1000.0;
upperLimit = 10000000000000000.0;
}
public override void Deposit(double amount)
{
this.balance += amount;
StateChangeCheck();
}
public override void WithDraw(double amount)
{
balance -= amount;
StateChangeCheck();
}
public override void PayInterest()
{
balance += interest * balance;
StateChangeCheck();
}
public override void StateChangeCheck()
{
if (balance < 0)
{
account.State = new RedState(this);
}
else if (balance < lowerLimit)
{
account.State = new SilverState(this);
}
}
}
/// <summary>
/// 账户类,维护一个具体状态类实例对象
/// 包含有状态类属性
/// </summary>
public class Account
{
private State _state;
private string owner;
public Account(string owner)
{
//初始状态为银色状态
this.owner = owner;
this._state = new SilverState(0.0, this);
}
/// <summary>
/// 状态属性
/// </summary>
public State State
{
get { return this._state; }
set { this._state = value; }
}
public double Balance
{
get { return _state.Balance; }
}
public void Deposit(double amount)
{
_state.Deposit(amount);
Console.WriteLine("存入 {0:C} --- ",amount);
Console.WriteLine("现存余额:{0:C}---",this.Balance);
Console.WriteLine("当前状态:{0}",this._state);
Console.WriteLine("");
}
public void WithDraw(double amount)
{
_state.WithDraw(amount);
Console.WriteLine("取出:{0:C}---",amount);
Console.WriteLine("现存余额:{0:C}---", this.Balance);
Console.WriteLine("当前状态:{0}", this._state);
Console.WriteLine("");
}
public void PayInterest()
{
_state.PayInterest();
Console.WriteLine("银行利息支付 ----");
Console.WriteLine("现存余额:{0:C}---", this.Balance);
Console.WriteLine("当前状态:{0}", this._state);
Console.WriteLine("");
}
}
客户端调用:
//状态模式
Account account = new Account("张三");
account.Deposit(500);
account.Deposit(300);
account.Deposit(650);
account.PayInterest();
account.WithDraw(2000);
account.WithDraw(1000);
Console.WriteLine();