我有一個銀行賬戶程序。每個賬戶可以處於初始狀態或可信賬戶狀態(目前)。未來可能會增加新的州。如果處於初始狀態,則不支付利息。但如果它在可信賬戶狀態,則支付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 –