`
chenying998179
  • 浏览: 25250 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

The Command Pattern Example in C#

 
阅读更多

The Command Pattern makes a execution request into an object. This makes it possible to store, search and transport requests and let clients call them via a common interface. This pattern is often used to implement undo or macro operations. A command has a execution method without any parameters to invoke the associated operation. The client can however provide context by setting properties.

In this example we build a simple vending machine console application, with cold beverages, hot coffee and peanuts (yes that’s very possible in my world). We implement the ICommand interface for each command to get the good stuff from the machine.

We also cheat a little by implementing the ICommandFactory Create() method on each command. This maybe violates the single responsibility principle, but gives us the convenience to write only one class if we need to add another command.

Command Pattern Class Diagram

A single implementation of a command, in this case the GetBeverage command, will look something like this.

using System;
using System.Diagnostics;

namespace CommandPatternConsole
{
    public class GetBeverageCommand : ICommand, ICommandFactory
    {
        public bool Sparkling { get; set; }

        #region ICommand Members

        public string Name
        {
            get { return "GetBeverage"; }
        }

        public string Description
        {
            get { return "GetBeverage [sparkling]"; }
        }

        public void Execute()
        {
            // Get some coffee
            Console.WriteLine(
                "Here's your drink {0} ",
                Sparkling ? "and it sparkles." : string.Empty);

            // Log the command
            Debug.WriteLine("{0}: {1} called",
                            DateTime.Now,
                            ToString());
        }

        #endregion

        #region ICommandFactory Members

        public ICommand Create(string[] args)
        {
            string arg1 = string.Empty;

            if (args.Length == 2)
            {
                arg1 = args[1];
            }

            return new GetBeverageCommand
                       {
                           Sparkling = arg1 == "sparkling",
                       };
        }

        #endregion
    }
}

A CommandParser tries to interpret the command line arguments. If it finds the right command it tries to create one with properties set by calling the Create() method with the arguments.

using System.Collections.Generic;
using System.Linq;

namespace CommandPatternConsole
{
    public class CommandParser
    {
        private readonly IEnumerable<ICommand> _commands;

        public CommandParser(IEnumerable<ICommand> commands)
        {
            _commands = commands;
        }

        internal ICommand Parse(string[] args)
        {
            string commandName = args[0];
            ICommand command = Find(commandName);

            return ((ICommandFactory) command).Create(args);
        }

        private ICommand Find(string commandName)
        {
            return _commands
                .FirstOrDefault(c => c.Name == commandName);
        }
    }
}

If all according to plan the command gets executed. If the parser can’t resolve the command, an exception is thrown and the application prints a list of possible commands to the console.

using System;
using System.Collections.Generic;

namespace CommandPatternConsole
{
    internal class Program
    {
        private static void Main(string[] args)
        {
            IEnumerable<ICommand> commands = GetCommands();

            try
            {
                var parser = new CommandParser(commands);
                ICommand command = parser.Parse(args);
                command.Execute();
            }
            catch (Exception)
            {
                Console.WriteLine("Invalid command {0}", args);
                PrintInstructions(commands);
            }
        }

        private static IEnumerable<ICommand> GetCommands()
        {
            return new List<ICommand>
                       {
                           new GetBeverageCommand(),
                           new GetCoffeeCommand(),
                           new GetPeanutsCommand(),
                       };
        }

        private static void PrintInstructions(IEnumerable<ICommand> commands)
        {
            Console.WriteLine();
            Console.WriteLine("*** VENDING MACHINE commands ***");
            Console.WriteLine();

            foreach (ICommand command in commands)
            {
                Console.WriteLine("- {0}", command.Description);
            }

            Console.WriteLine();
        }
    }
}

Vending Machine Console

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics