poniedziałek, 9 lipca 2012

[Wzorce projektowe] Command

Analogia z życia:

Gdy zepsuje nam się pralka dzwonimy po fachowca. Do jego zadań należy dojechać na miejsce, zlokalizować usterkę i naprawić urządzenie. Może się tak jednak zdarzyć, że w międzyczasie coś nam wypadnie i będziemy zmuszeni przesunąć wizytę. Wtedy również bierzemy telefon i informujemy fachowca o nowym terminie. W przypadku, gdy się rozmyślimy i postanowimy kupić nową pralkę, bierzemy telefon i odwołujemy wizytę.



Zastosowanie:


Zadaniem wzorca polecenia jest reprezentowanie akcji jako osobnego obiektu. Umożliwia to odseparowanie klienta, który tę akcję wywołuje od obiektu zajmującego się wywołaniem akcji wraz z jego zależnościami. Podejście takie umożliwia między innymi kolejkowanie akcji, walidację lub cofanie akcji już wykonanych. Z punktu widzenia klienta jest to wywoływanie pojedynczych metod, natomiast cała logika zakodowana zostaje w obiekcie reprezentującym akcję.

Zasada działania:

Komenda reprezentowana jest przez interfejs wystawiający proste, bezparametrowe metody typu wywołaj, waliduj, cofnij. Metody te są wołane przez klienta, gdy zachodzi taka potrzeba.

Przykład implementacyjny:

public interface ICommand
    {
        void Execute();
    }

    public class ExitCommand : ICommand
    {
        public void Execute()
        {
            Environment.Exit(0);
        }
    }

    public class ClearCommand : ICommand
    {
        public void Execute()
        {
            Console.Clear();
        }
    }

    public class AboutCommand : ICommand
    {
        public void Execute()
        {
            Console.WriteLine("This is sample program");
        }
    }

    public class NoSuchCommand : ICommand
    {
        public void Execute()
        {
            Console.WriteLine("Error - no such command");
        }
    }
  public class SimpleCommandFactory
    {
        private List<ICommand> _commands;

        public SimpleCommandFactory()
        {
            _commands = new List<ICommand>()
                            {
                                new AboutCommand(),
                                new ClearCommand(),
                                new ExitCommand()
                            };
        }

        public ICommand GetCommand(string name)
        {
            var cmd = _commands.FirstOrDefault(s => s.GetType().Name.Contains(name));
            if (cmd != null)
                return cmd;
            return new NoSuchCommand();
        }

        public void PrintAvailableCommands()
        {
            foreach (ICommand command in _commands)
            {
                Console.WriteLine(command.GetType().Name);
            }
        }
    }
 class Program
    {
        static void Main(string[] args)
        {
            var factory = new SimpleCommandFactory();
            Console.WriteLine("Available Commands Are :");
            factory.PrintAvailableCommands();
            while (true)
            {
                var arg = Console.ReadLine();
                var cmd = factory.GetCommand(arg);
                cmd.Execute();
            }
        }
    }

Brak komentarzy:

Prześlij komentarz