用户需求:
设计思路:
1.UML图
具体代码实现:
抽象状态类
AccountState类
public abstract class AccountState
{
protected clubAccount Account;
//存款
public abstract void Deposit(double amount);
//消费
public abstract void Consume(double amount);
//检查账户状态
public abstract void StateCheck();
}
具体状态类
VistorState类
public class VistorState : AccountState
{
public VistorState(clubAccount account)
{
Account = account;
}
public override void Deposit(double amount)
{
Account.Balance += amount;
Console.WriteLine("向名为"+Account.Owner+"的账户中存款"+amount+"元,存款后账户余额为"+Account.Balance+"元");
StateCheck();
}
public override void Consume(double amount)
{
double newBalance = Account.Balance - amount;
if (newBalance > 0)
{
Account.Balance = newBalance;
Console.WriteLine("向名为" + Account.Owner + "的账户中消费" + amount + "元,存款后账户余额为" + Account.Balance + "元");
StateCheck();
}
else
{
Console.WriteLine("你的账户余额不足,无法消费,请先存款");
}
StateCheck();
}
public override void StateCheck()
{
if (Account.Balance > 100 && Account.Balance <= 1000)
{
Account.State = new MenberState(Account);
}
else if (Account.Balance > 1000)
{
Account.State = new VIPState(Account);
}
}
}
MenberState类
public class MenberState : AccountState
{
public MenberState(clubAccount account)
{
Account = account;
}
public override void Deposit(double amount)
{
Account.Balance += amount;
Console.WriteLine("向名为" + Account.Owner + "的账户中存款" + amount + "元,存款后账户余额为" + Account.Balance + "元");
StateCheck();
}
public override void Consume(double amount)
{
double newBalance = Account.Balance - amount;
if (newBalance > 0)
{
Account.Balance = newBalance;
Console.WriteLine("向名为" + Account.Owner + "的账户中消费" + amount + "元,存款后账户余额为" + Account.Balance + "元");
StateCheck();
}
else
{
Console.WriteLine("你的账户余额不足,无法消费,请先存款");
}
StateCheck();
}
public override void StateCheck()
{
if (Account.Balance > 0&& Account.Balance <= 100)
{
Account.State = new VistorState(Account);
}
else if (Account.Balance > 1000)
{
Account.State = new VIPState(Account);
}
}
}
VIPState类
public class VIPState : AccountState
{
public VIPState(clubAccount account)
{
Account = account;
}
public override void Deposit(double amount)
{
Account.Balance += amount;
Console.WriteLine("向名为" + Account.Owner + "的账户中存款" + amount + "元,存款后账户余额为" + Account.Balance + "元");
StateCheck();
}
public override void Consume(double amount)
{
double newBalance = Account.Balance - amount;
if (newBalance > 0)
{
Account.Balance = newBalance;
Console.WriteLine("向名为" + Account.Owner + "的账户中消费" + amount + "元,存款后账户余额为" + Account.Balance + "元");
StateCheck();
}
else
{
Console.WriteLine("你的账户余额不足,无法消费,请先存款");
}
StateCheck();
}
public override void StateCheck()
{
if (Account.Balance > 0 && Account.Balance <= 100)
{
Account.State = new VistorState(Account);
}
else if (Account.Balance >100 && Account.Balance<=1000)
{
Account.State = new MenberState(Account);
}
}
}
环境类
clubAccount类
public class clubAccount
{
public AccountState State { get; set; }
public double Balance { get; set; }
public string Owner { get; set; }
public clubAccount(string owner, double initialAmount)
{
Owner = owner;
Balance = initialAmount;
State = new VistorState(this);
}
public void SetBalance(double amount)
{
Balance = amount;
}
public void Deposit(double amount)
{
Console.WriteLine("现要存款" + amount + "元");
State.Deposit(amount);
Console.WriteLine("账户状态变为" + State);
}
public void Consume(double amount)
{
Console.WriteLine("现要消费" + amount + "元");
State.Consume(amount);
Console.WriteLine("账户状态变为" + State);
}
}
客户端
static void Main(string[] args)
{
clubAccount account = new clubAccount("张三", 0);
Console.WriteLine("开户成功,姓名:" + account.Owner + ",初始金额:" + account.Balance);
Console.WriteLine("------------------------");
account.Deposit(50);
Console.WriteLine("------------------------");
account.Deposit(100);
Console.WriteLine("------------------------");
account.Deposit(1000);
Console.WriteLine("------------------------");
account.Consume(500);
Console.WriteLine("------------------------");
account.Consume(200);
Console.WriteLine("------------------------");
account.Consume(400);
Console.WriteLine("------------------------");
account.Consume(100);
Console.WriteLine("------------------------");
Console.ReadLine();
}
运行结果
总结
优点:封装了转换规则
将所有与某个状态有关的行为放到一个类中,并且可以方便地增加新的状态,只需要改变对象状态即可改变对象的行为
允许状态转换逻辑与状态对象合为一体,而不是某一个巨大的条件语句块
可以让多个环境对象共享一个状态对象,从而减少系统中对象的个数
缺点:状态模式的使用必然会增加系统类和对象的个数
状态模式的结构与实现都较为复杂,如果使用不当将导致程序结构与代码的混乱
状态模式对“开闭原则”的支持并不太好,对于可以切换状态的状态模式,增加新的状态
类需要修改那些负责状态转换的源代码,否则无法切换到新增状态;而且修改某个状态类的行为也需修改对应类的源代码