design-patterns - command pattern c#
Command Pattern parece innecesariamente complejo(¿qué estoy deficiente en entender?) (3)
Bueno, si lo pones de esa manera, parece bastante complejo, pero a menudo un Receptor no necesita ser un objeto en absoluto. Puede ser poco más que una función que se ejecuta (como un evento). Además, el invocador no necesita ser una clase. Es solo lo que desencadena el comando. Esto también puede ser un controlador de eventos en un botón.
Incluso Wikipedia resume un par de ejemplos en los que se usa este patrón sin tener que implementar clases separadas para el invocador y el receptor. Un ejemplo es un diálogo de asistente, donde la GUI rellena el objeto de comando y un botón de Finalización lo desencadena. Entonces, esa clase de GUI (que tiene de todos modos) es tanto el cliente como el invocador.
He leído sobre el patrón de comando, y creo que me estoy perdiendo algo. El objeto Command existe para abstraer los detalles del objeto Receiver. Me parece que simplemente podríamos detenernos aquí y mantener referencias a los objetos Command para ejecutar el método apropiado en el momento apropiado.
¿Por qué, entonces, se necesita Invoker? ¿Qué ventaja proporciona esta indirección adicional? Ya hemos ocultado los detalles del Receptor detrás del Comando, ¿cuál es la motivación para que el Comando se oculte también al cliente?
Por lo que puedo decir, el objetivo del patrón es tener algún tipo de productor de comandos y algún tipo de consumidor de comandos, pero permitir al productor crear o modificar comandos sin que el consumidor cambie.
El patrón llama al productor el "Cliente" y al consumidor el "Invitante".
Es una devolución de llamada OO.
¿Por qué, entonces, se necesita Invoker?
Por lo que puedo decir de todos los ejemplos en Wikipedia , el invocador no tiene una forma definida. Es simplemente un código que acepta un comando abstracto.
Me parece que podríamos simplemente detenernos aquí y mantener referencias a los objetos de Comando
Si tiene sentido en su código para lo que invoca comandos para aceptar o mantener referencias a comandos abstractos, entonces ya ha implementado el invocador.
Si un bit de código es tanto el productor como el consumidor, el patrón de comando no tiene valor. Solo vale la pena cuando pases comandos abstractos a algo que quiera invocarlos.
Si pasas diferentes tipos de comandos, Invoker
es útil. Puede usar el mismo Invoker para la ejecución de diferentes comandos concretos. En un nodo diferente, etiquetar Receiver
con ConcreteCommand
lugar de Invoker
permite un acoplamiento flexible. El Receiver
puede cambiar el nombre del método (por ejemplo, switchOn a swithcOnTV) como en este ejemplo:
Publicación relacionada: Uso del patrón de diseño de comando
Para entender el propósito de Invoker
, me gustaría que consulte este artículo sobre los casos de uso del centro de servicio de restaurante y automóvil.
El camarero ( Invoker
) recibe el pedido del Customer
en su bloc. La Order
se pone en cola para la orden de cocción y llega al cocinero ( Receiver
) donde se procesa.
El cliente es el Customer
Envía su solicitud al Receiver
través del camarero, que es el Invoker
. El camarero encapsula el comando (el orden en este caso) escribiéndolo en el cheque y luego lo coloca, creando el objeto ConcreteCommand
que es el comando mismo.
El Receiver
será el cocinero que, después de completar el trabajo en todas las órdenes que le fueron enviadas antes del comando en cuestión, comienza a trabajar en ello.
Otro aspecto notable del ejemplo es el hecho de que el pad para los pedidos no admite solo pedidos del menú, por lo que puede admitir comandos para cocinar muchos artículos diferentes.