gpt4 book ai didi

c# - 减少状态模式中的耦合

转载 作者:行者123 更新时间:2023-11-30 20:51:53 25 4
gpt4 key购买 nike

我有一个银行账户程序。每个帐户都可以处于初始状态或受信任帐户状态(当前)。将来可能会添加新的状态。如果它处于初始状态,则不支付利息。但是如果是Trusted Account State,则支付9%的利息。

以下代码有效。但是 ChangeState() 方法中存在紧密耦合。 InitialAccountState 需要知道 TrustedAccountedState 的存在。如果我们添加一个名为 VeteranAccountedState 的新状态,则 ChangeState() 方法需要在 InitialAccountState 类中重写。

减少这种耦合的最佳 .Net 4.0 方法是什么?

状态模式

The state pattern allows a object's state to change at any given moment which actually alters its behavior.

当状态变化的顺序被预定义时,耦合在状态模式中不是问题。例如,交通灯总是从绿—黄—红变化。在这种情况下,耦合不是问题——Green 确信在下一步中它始终是 Yellow 状态。引用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);
}
}

客户

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();
}
}

引用文献

  1. Analysis Of State Machine Pattern
  2. Is the State Design pattern scalable ?
  3. State Design Pattern
  4. Implementing the Specification Pattern in .NET
  5. Is the Specification Pattern obsolete?
  6. Specification pattern in C#
  7. Specifications in C# 3.0
  8. LINQ Expression Trees and the Specification Pattern

最佳答案

我会将状态更改重构为另一个类,例如服务类,其职责是了解如何更改状态,从而反转依赖关系并消除状态之间的紧密耦合。所以我会更改抽象类,以便可以访问 protected 属性。

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 类就像一个 Controller ,它看起来像

    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 类将不需要保持状态,而只是定义行为,即如果您的帐户处于给定状态,Deposit 或 PayInterest 应该如何表现。您仍然可以在 statechanger 类中使用规范模式。

关于c# - 减少状态模式中的耦合,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21332730/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com