Results 1 to 2 of 2
  1. #1
    Join Date
    Aug 2013
    Posts
    25

    C# 102 Command/State Question

    In C# 102, I'm a bit stuck while working on my own implementation of the text-based adventure game. The confusion I'm having comes in with the commands and states we are using. The way I currently envision it is that the only responsibility of a command is to initialize a new state, given certain arguments, and that the state is what handles the execution of that code.

    For example (pseudocode-ish, due to all my projects being on my failed laptop hard drive)...
    Code:
    class SaveCommand : ICommand
    {
        private string _saveLocation;
        private IState _previousState;
        
        public SaveCommand(string saveLocation, IState previousState)
        {
            _saveLocation = saveLocation;
            _previousState = previousState;
        }
        
        public void Execute()
        {
            SaveState(saveLocation, previousState);
        }
    }
    
    class SaveState : IState
    {
        //fields
    
        public SaveState(string saveLocation, IState previousState)
        {
            //initialize fields
        }
        
        public void Run()
        {
            //write to save file, found in location argument
            //return to previousState
        }
    }
    But then when I look at it this way, it seems that the command is just adding an extra, unnecessary step, which is why I see that something else has to be done in the command. But then what happens in the state?

    In other words, what is the responsibility of the command, and what is the responsibility of the state?

  2. #2
    Join Date
    Mar 2013
    Location
    Australia
    Posts
    217
    I'm not sure if i get the problem but i think i see what its trying to teach.

    I think the key to this pattern is the ICommand interface. What if you wanted to be able to process an unknown amount of commands. You wouldn't want to have to add code every time you add a command so it knows how to process that command.

    Instead we can have something that processes commands like this

    Code:
        interface ICommand
        {
            void Execute();
        }    
    
        public class CommandExecuter
        {
            public void ExecuteCommand(ICommand command)
            {
                command.Execute();
            }
        }
    The Command Executer knows only one job and thats how to execute an ICommand. ICommand is the contract that any command has to implement. So we know every command that implements the ICommand interface will have the Execute method Implementation for that type of command.

    So we can call the CommandExecuter's execute command method and pass in a SaveCommand.

    Code:
        class Program
        {
            static void Main(string[] args)
            {
                var commandExecuter = new CommandExecuter();
                
                commandExecuter.ExecuteCommand(new SaveCommand();
            }
    
        }
    Now to add commands we just create the new class that implements the ICommand interface.

    Code:
        class ExitCommand : ICommand
        {
            public void Execute()
            {
                Application.Exit();
            }
        }
    
        class SayGoodbyeCommand : ICommand
        {
            public string UserName { get; set; }
    
            public SayGoodbyeCommand(string userName)
            {
                UserName = userName;
            }
    
            public void Execute()
            {
                Console.WriteLine("Goodbye {0}", UserName);
            }
        }
    The Command Executer does not need to change because it takes in any object that implements the ICommmand interface. So it already knows it cal call the Execute Method on that object

    Code:
        class Program
        {
            static void Main(string[] args)
            {
                var commandExecuter = new CommandExecuter();
                commandExecuter.ExecuteCommand(new SayGoodbyeCommand());
                commandExecuter.ExecuteCommand(new SaveCommand();
                commandExecuter.ExecuteCommand(new ExitCommand());
            }
    
        }
    
        class CommandExecuter
        {
            public void ExecuteCommand(ICommand command)
            {
                command.Execute();
            }
        }

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •