Cómo usar el patrón de diseño de comandos en C #

Los patrones de diseño son soluciones comprobadas que se utilizan para resolver problemas de diseño comunes y reducir las complejidades del código. Los patrones de diseño de Gang of Four se dividen en tres categorías:

  • Creacional: patrones relacionados con la creación de objetos
  • Estructural: patrones relacionados con el ensamblaje de objetos
  • Comportamiento: patrones relacionados con la colaboración de objetos y la separación de responsabilidades

El patrón de diseño de comandos se incluye en la categoría de patrones de comportamiento. Este artículo explora cómo podemos trabajar con el patrón de diseño de comandos en C #.

¿Cuál es el patrón de diseño de comandos?

La intención del patrón de diseño del comando es desacoplar al solicitante de una acción del objeto que ejecuta la acción. En el patrón de diseño de comandos, una solicitud se encapsula como un objeto que contiene toda la información sobre la solicitud. Este objeto luego se pasa a un objeto invocador. El objeto invocador luego busca el objeto apropiado para manejar el comando y pasa el comando al objeto.

El patrón de diseño de comandos es una buena opción cuando desea implementar devoluciones de llamada, tareas en cola, historial de seguimiento y funcionalidad de deshacer / rehacer en su aplicación. El patrón de comando es una buena opción para implementar mecanismos de reintento, cuando su aplicación desea volver a intentar conectarse a un servicio en un momento posterior que no está funcionando en este momento. El patrón Command también se usa en aplicaciones de cola de mensajes, es decir, en aplicaciones que necesitan recuperarse de la pérdida de datos.

Participantes del patrón de diseño de comandos

En una implementación clásica del patrón de Comando, tienes cuatro componentes: el comando, el invocador, el receptor y el cliente. Los participantes en el patrón de diseño de comandos incluyen los siguientes:

  • Comando: proporciona una interfaz para ejecutar una operación
  • ConcreteCommand: amplía la interfaz de comandos e implementa el método Execute
  • Cliente: crea una instancia de una clase ConcreteCommand
  • Invocador: informa al comando para ejecutar la solicitud
  • Receptor: contiene la lógica para ejecutar las operaciones asociadas con la solicitud

Ejemplo de patrón de diseño de comandos en C #

En la siguiente sección exploraremos cómo podemos implementar el patrón de diseño de comandos. En nuestro ejemplo, implementaremos una calculadora simple usando las siguientes clases:

  • Comando (Clase base abstracta de comando)
  • SimpleCalculator (clase de receptor)
  • AddCommand (clase de comando concreta)
  • SubstractCommand (clase de comando concreta)
  • Multiplicar comando (clase de comando concreto)
  • DivideCommand (clase de comando concreta)
  • Invoker (clase de Invoker)

Cree la clase base abstracta Command en C #

Considere la siguiente clase base abstracta denominada Command que contiene la declaración del método Execute.

Comando de clase abstracta pública

    {

        receptor protegido SimpleCalculator;

        comando público (receptor SimpleCalculator)

        {

            this.receiver = receptor;

        }

        public abstract int Execute ();

    }

La siguiente enumeración muestra las operaciones que serán compatibles con nuestra calculadora simple.

Public enum CommandOption

    {

        Sumar, restar, multiplicar, dividir

    }

Crear la clase Receiver en C #

La siguiente es una clase llamada SimpleCalculator. Esta clase actúa como Receptor y contiene la definición de los métodos Sumar, Restar, Multiplicar y Dividir.

clase pública SimpleCalculator

    {

        privado int _x, _y;

        calculadora simple pública (int a, int b)

        {

            _x = a;

            _y = b;

        }

        public int Add ()

        {

            return _x + _y;

        }

        public int Restar ()

        {

            return _x - _y;

        }

        public int Multiplicar ()

        {

            return _x * _y;

        }

        public int Divide ()

        {

            return _x / _y;

        }

    }

Cree las clases de comando concretas en C #

Las clases de comando concretas amplían la clase base abstracta de comando e implementan el método Execute como se muestra a continuación.

 AddCommand de clase pública: comando

    {

        privada SimpleCalculator _calculator;

        AddCommand público (calculadora SimpleCalculator): base (calculadora)

        {

            _calculator = calculadora;

        }

        public override int Execute ()

        {

            return _calculator.Add ();

        }

    }

    SubtractCommand de clase pública: Comando

    {

        privada SimpleCalculator _calculator;

        public SubtractCommand (calculadora SimpleCalculator):

        base (calculadora)

        {

            _calculator = calculadora;

        }

        public override int Execute ()

        {

            return _calculator.Subtract ();

        }

    }

    clase pública MultiplyCommand: Command

    {

        privada SimpleCalculator _calculator;

        public MultiplyCommand (calculadora SimpleCalculator):

        base (calculadora)

        {

            _calculator = calculadora;

        }

        public override int Execute ()

        {

            return _calculator.Multiply ();

        }

    }

    clase pública DivideCommand: Command

    {

        privada SimpleCalculator _calculator;

        public DivideCommand (calculadora SimpleCalculator):

        base (calculadora)

        {

            _calculator = calculadora;

        }

        public override int Execute ()

        {

            return _calculator.Divide ();

        }

    }

Crear la clase Invoker en C #

El siguiente fragmento de código ilustra la clase Invoker. Contiene dos métodos, SetCommand y Execute. Mientras que SetCommand se usa para asignar el objeto de comando a la referencia de comando privada en la clase Invoker, Execute se usa para ejecutar el comando.

    invocador de clase pública

    {

        comando privado _comando;

        public void SetCommand (comando de comando)

        {

            _command = comando;

        }

        public int Execute ()

        {

            return _command.Execute ();

        }

    }

El patrón de diseño de comandos en acción en C #

Finalmente, el siguiente fragmento de código ilustra cómo puede realizar un cálculo simple usando la clase SimpleCalculator.

static void Main (cadena [] argumentos)

        {

            Calculadora SimpleCalculator = nueva SimpleCalculator (15, 3);

            var addCommand = new AddCommand (calculadora);

            var substractCommand = new SubtractCommand (calculadora);

            var multiplyCommand = new MultiplyCommand (calculadora);

            var divideCommand = new DivideCommand (calculadora);

            Invoker invoker = nuevo Invoker ();

            invoker.SetCommand (addCommand);

            Console.WriteLine ("El resultado es {0}", invoker.Execute ());

            invoker.SetCommand (substractCommand);

            Console.WriteLine ("El resultado es {0}", invoker.Execute ());

            invoker.SetCommand (multiplyCommand);

            Console.WriteLine ("El resultado es {0}", invoker.Execute ());

            invoker.SetCommand (divideCommand);

            Console.WriteLine ("El resultado es {0}", invoker.Execute ());

            Console.ReadLine ();

        }

El patrón de diseño de comandos proporciona soporte para la extensibilidad y reduce el acoplamiento que existe entre el invocador y el receptor de un comando. Dado que la solicitud está encapsulada en un objeto independiente, puede parametrizar métodos con diferentes solicitudes, guardar solicitudes en una cola e incluso brindar soporte para operaciones que se pueden rehacer o deshacer.

-

Haga más con C #:

  • Cómo trabajar con AutoMapper en C #
  • Cuándo usar una clase abstracta frente a una interfaz en C #
  • Cómo trabajar con subprocesos en C #
  • Cómo usar Dapper ORM en C #
  • Cómo implementar el patrón de diseño del repositorio en C #
  • Cómo implementar un registrador simple en C #
  • Cómo trabajar con delegados en C #
  • Cómo trabajar con delegados Action, Func y Predicate en C #
  • Cómo trabajar con log4net en C #
  • Cómo trabajar con la reflexión en C #