В настоящее время я изучаю паттерн государственного проектирования и думаю, что мне довольно понятно, как он работает. Я рассматривал концептуальный пример, который я опубликовал ниже. Есть только одна часть кода, которую я не совсем понимаю.
using System;
namespace BranchingDemo
{
class Program
{
static void Main(string[] args)
{
Console.ReadLine();
}
}
// State Interface
interface IAccountState
{
IAccountState Deposit(Action addToBalance);
IAccountState Withdraw(Action subtractFromBalance);
IAccountState Freeze();
IAccountState HolderVerified();
IAccountState Close();
}
//Context
class Account
{
public decimal Balance { get; private set; }
private IAccountState State { get; set; }
public Account(Action onUnfreeze)
{
this.State = new NotVerified(onUnfreeze);
}
public void Deposit(decimal amount)
{
this.State = this.State.Deposit(() => { this.Balance += amount; });
}
public void Withdraw(decimal amount)
{
this.State = this.State.Withdraw(() => { this.Balance -= amount; });
}
public void HolderVerified()
{
this.State = this.State.HolderVerified();
}
public void Close()
{
this.State = this.State.Close();
}
public void Freeze()
{
this.State = this.State.Freeze();
}
}
//Concrete State
class Active : IAccountState
{
private Action OnUnfreeze { get; }
public Active(Action onUnfreeze)
{
this.OnUnfreeze = onUnfreeze;
}
public IAccountState Deposit(Action addToBalance)
{
addToBalance();
return this;
}
public IAccountState Withdraw(Action subtractFromBalance)
{
subtractFromBalance();
return this;
}
public IAccountState Freeze() => new Frozen(this.OnUnfreeze);
public IAccountState HolderVerified() => this;
public IAccountState Close() => new Closed();
}
//Concrete State
class Closed : IAccountState
{
public IAccountState Deposit(Action addToBalance) => this;
public IAccountState Withdraw(Action subtractFromBalance) => this;
public IAccountState Freeze() => this;
public IAccountState HolderVerified() => this;
public IAccountState Close() => this;
}
}
В конкретном классе Active есть свойство типа делегат действия, которое передается как параметр в его конструкторе. Также в конструкторе класса контекста в качестве параметра передается делегат действия типа. Теперь концептуально я понимаю, что это делается, поскольку это обеспечивает обратную ссылку на объект контекста (учетную запись) с состоянием, то есть закрытым или активным. Эта обратная ссылка может использоваться Состояниями для перехода контекста в другое Состояние. Мой первый вопрос: почему использовался делегат?
Однако я пытался запустить код и отладить его, чтобы проиллюстрировать, что происходит. Поэтому мой вопрос в коде: как мне инициализировать новую учетную запись? Аккаунты начинаются с состояния NotVerified. Я пробовал этот код.
Action initialState = () => { };
Account account= new Account(initialState);
Если я затем хочу определить состояние учетной записи, как мне это закодировать?