我有一个银行账户程序。每个账户可以处于初始状态或可信账户状态(目前)。未来可能会增加新的州。如果处于初始状态,则不支付利息。但如果它在可信账户状态,则支付9%的利息。减少状态模式中的耦合
以下代码有效。但ChangeState()方法中存在紧密耦合。 InitialAccountState
需要知道TrustedAccountedState
的存在。如果我们添加一个名为VeteranAccountedState
的新状态,则需要在InitialAccountState
类中重写ChangeState()方法。
什么是最好的.Net 4.0的方式来减少这种耦合?
状态模式
状态模式允许一个对象的状态在任何给定的时刻,实际上改变了其行为改变。
状态变化的顺序是预先定义的时,耦合不是状态模式的问题。例如,交通信号灯将总是从绿 - 黄 - 红变化。在这种情况下,耦合不是问题 - 绿色可以肯定它在下一步中总是处于黄色状态。请参阅Analysis Of State Machine Pattern
抽象状态
abstract class AccountState
{
// Properties
public BankAccount Account { get; set; }
public double Balance { get; set; }
protected double interest;
protected double lowerLimit;
protected double upperLimit;
public abstract void Deposit(double amount);
public abstract void PayInterest();
}
混凝土
class InitialAccountState : AccountState
{
public InitialAccountState(AccountState state) :this(state.Balance, state.Account)
{
}
public InitialAccountState(double balance, BankAccount account)
{
this.Balance = balance;
this.Account = account;
Initialize();
}
private void Initialize()
{
lowerLimit = 0.0;
upperLimit = 1000.0;
}
public override void Deposit(double amount)
{
Balance += amount;
ChangeState();
}
public override void PayInterest()
{
throw new Exception("No Interest Allowed");
}
private void ChangeState()
{
if (Balance > upperLimit)
{
Account.State = new TrustedAccountedState(this);
}
}
}
class TrustedAccountedState : AccountState
{
public TrustedAccountedState(AccountState state): this(state.Balance, state.Account)
{
}
public TrustedAccountedState(double balance, BankAccount account)
{
this.Balance = balance;
this.Account = account;
Initialize();
}
private void Initialize()
{
interest = 0.05;
lowerLimit = 1000.0;
upperLimit = 10000000.0;
}
public override void Deposit(double amount)
{
Balance += amount;
ChangeState();
}
public override void PayInterest()
{
Balance += interest * Balance;
ChangeState();
}
private void ChangeState()
{
if (Balance < lowerLimit)
{
Account.State = new InitialAccountState(this);
}
}
}
背景
class BankAccount
{
// Properties
public AccountState State { get; set; }
public double Balance
{
get { return State.Balance; }
}
// Constructor
public BankAccount(string owner)
{
this.State = new InitialAccountState(0.0, this);
}
public void Deposit(double amount)
{
State.Deposit(amount);
Console.WriteLine("Deposited {0:C} --- ", amount);
Console.WriteLine(" Balance = {0:C}", this.Balance);
Console.WriteLine(" Status = {0}", this.State.GetType().Name);
Console.WriteLine("");
}
public void PayInterest()
{
State.PayInterest();
Console.WriteLine("INTEREST PAID --- ");
Console.WriteLine(" Balance = {0:C}", this.Balance);
Console.WriteLine(" Status = {0}\n", this.State.GetType().Name);
}
}
个CLIENT
class Program
{
static void Main(string[] args)
{
BankAccount account = new BankAccount("Jim Johnson");
account.Deposit(500.0);
account.Deposit(300.0);
account.Deposit(550.0);
account.PayInterest();
Console.ReadKey();
}
}
参考
- Analysis Of State Machine Pattern
- Is the State Design pattern scalable ?
- State Design Pattern
- Implementing the Specification Pattern in .NET
- Is the Specification Pattern obsolete?
- Specification pattern in C#
- Specifications in C# 3.0
- LINQ Expression Trees and the Specification Pattern
您可能想要考虑规范模式:http://en.wikipedia.org/wiki/Specification_pattern –