locked
Conceptual example of State Design Pattern in C# RRS feed

  • Question

  • I am currently studying the state Design Pattern and I think I pretty clear about how it works. I was looking at a conceptual example which I have posted below. There is just one part of the code that I don't quite understand.

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

    In the concrete class Active there is property of type action delegate which is passed as a parameter in its constructor. Also in the constructor of the context class a delegate of type action is passed as a parameter. Now conceptually I understand this is done as this provides a backreference to the Context object (Account),with the State i.e. closed or Active. This backreference can be used by States to transition the Context to another State. My first question is why a delegate was used?

    Moreover I was trying to get the code to run and debug to illustrate what was happening. Therefore my question is in the code how do I need initialize a new Account? Accounts begin with a NotVerified state. I tried this code.

    Action initialState = () => { };
                Account account= new Account(initialState);
    If I then want to determine the state of the account how do I code that?



    Sunday, May 31, 2020 6:48 AM

Answers

  • Hi Sauce1979,

    Thank you for posting here.

    In the Account class, there is an attribute: State.

    I think it should be public so that users can get the status value.

    Best Regards,

    Timon


    MSDN Community Support
    Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.

    • Marked as answer by Sauce1979 Monday, June 1, 2020 3:13 PM
    Monday, June 1, 2020 6:39 AM

All replies

  • Hi Sauce1979,

    Thank you for posting here.

    In the Account class, there is an attribute: State.

    I think it should be public so that users can get the status value.

    Best Regards,

    Timon


    MSDN Community Support
    Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.

    • Marked as answer by Sauce1979 Monday, June 1, 2020 3:13 PM
    Monday, June 1, 2020 6:39 AM
  • Hi Timon,

    Thanks for your response. Setting the State attribute to public did the trick.

    Monday, June 1, 2020 3:13 PM