[英]Reduce Coupling in State Pattern
我有一个银行账户程序。 每个账户都可以处于初始状态或可信账户状态(目前)。 将来可能会添加新的状态。 如果处于初始状态,则不支付利息。 但如果它处于受信任帐户状态,则支付 9% 的利息。
以下代码有效。 但是 ChangeState() 方法中存在紧密耦合。 InitialAccountState
需要知道TrustedAccountedState
的存在。如果我们添加一个名为VeteranAccountedState
的新状态,则需要在InitialAccountState
类中InitialAccountState
() 方法。
减少这种耦合的最佳 .Net 4.0 方法是什么?
状态模式
状态模式允许对象的状态在任何给定时刻改变,这实际上改变了它的行为。
当状态变化的顺序是预定义的时,耦合不是状态模式中的问题。 例如,交通灯总是会从绿-黄-红变化。 在这种情况下,耦合不是问题——绿色确信在下一步中它总是会是黄色状态。 参考状态机模式分析
抽象状态
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);
}
}
客户
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();
}
}
参考
我会将状态的更改重构为另一个类,例如服务类,其职责是了解如何更改状态,从而反转依赖关系并消除状态之间的紧密耦合。 所以我会更改抽象类,以便可以访问受保护的属性。
abstract class AccountState
{
// Properties
public BankAccount Account { get; set; }
public double Balance { get; set; }
internal double interest;
internal double lowerLimit;
internal double upperLimit;
public abstract void Deposit(double amount);
public abstract void PayInterest();
}
添加一个 StateChanger 类...
public class StateChanger(){
public AccountState ChangeState(AccountState state){
if((state is InitialAccountState) && (state.Balance > state.upperLimit)){
return new TrustedAccountedState(state);
}
if((state is TrustedAccountedState) && (state.Balance < state.lowerLimit))
{
return new InitialAccountState(state);
}
return state;
}
}
从 AccountState 类中删除依赖项
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;
}
public override void PayInterest()
{
throw new Exception("No Interest Allowed");
}
}
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;
}
public override void PayInterest()
{
Balance += interest * Balance;
}
}
然后你的 BackAccount 类就像一个控制器,它看起来像
class BankAccount
{
// Properties
public AccountState State { get; set; }
private StateChanger stateChanger;
public double Balance
{
get { return State.Balance; }
}
// Constructor
public BankAccount(string owner,StateChanger stateChanger)
{
this.State = new InitialAccountState(0.0, this);
this.stateChanger = stateChanger;
}
public void Deposit(double amount)
{
State.Deposit(amount);
State = stateChanger.ChangeState(State);
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();
State = stateChanger.ChangeState(State);
Console.WriteLine("INTEREST PAID --- ");
Console.WriteLine(" Balance = {0:C}", this.Balance);
Console.WriteLine(" Status = {0}\n", this.State.GetType().Name);
}
}
和主要
class Program
{
static void Main(string[] args)
{
StateChanger stateChanger = new StateChanger();
BankAccount account = new BankAccount("Jim Johnson",stateChanger);
account.Deposit(500.0);
account.Deposit(300.0);
account.Deposit(550.0);
account.PayInterest();
Console.ReadKey();
}
}
通过分离管理状态的关注点,AccountState 类彼此分离,现在如果您需要添加更多状态,则只需更新 1 个类。 然后,AccountState 类将不需要保持状态,而是只定义行为,即如果您的帐户处于给定状态,存款或支付利息应如何表现。 您仍然可以在 statechanger 类中使用规范模式。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.