Este patrón suele establecer en escenarios donde se necesite encapsular una petición dentro de un objeto, permitiendo parametrizar a los clientes con distintas peticiones, encolarlas, guardarlas en un registro de sucesos o implementar un mecanismo de deshacer/repetir.
Se debe usar cuando:
- Se necesiten colas o registros de mensajes.
- Se deba tener la posibilidad de deshacer las operaciones realizadas.
- Se necesite uniformidad al invocar las acciones.
- Se quiera facilitar la parametrización de las acciones a realizar.
- Se quiera independizar el momento de petición del de ejecución.
- El parámetro de una orden puede ser otra orden a ejecutar.
- Se busque desarrollar sistemas utilizando órdenes de alto nivel que se construyen con operaciones sencillas (primitivas).
- Se necesite sencillez al extender el sistema con nuevas acciones.
Diagrama UML
Command: declara una interfaz para ejecutar una operación.
CommandConcreto: define un enlace entre un objeto “Receiver” y una acción. Implementa el método execute invocando la(s) correspondiente(s) operación(es) del “Receiver”.
Cliente: crea un objeto “CommandConcreto” y establece su receptor.
Invoker: le pide a la orden que ejecute la petición.
Receiver: sabe como llevar a cabo las operaciones asociadas a una petición. Cualquier clase puede hacer actuar como receptor.
El cliente crea un objeto “CommandConcreto” y especifica su receptor. Un objeto “Invoker” almacena el objeto “CommandConcreto”. El invocador envía una petición llamando al método execute sobre la orden.
El objeto “CommandConcreto”, invoca operaciones de su receptor para llevar a cabo la petición.
Ejemplo
Escenario: una empresa maneja varios servidores y cada uno de ellos deben correr diversos procesos, como apagarse, prenderse, etc. Cada uno de estos procesos, a su vez, implican pequeños pasos como, por ejemplo, realizar una conexión a dicho servidor, guardar los datos en un log, etc.
Dado que cada servidor tiene su propia lógica para cada operación, se decidió crear una interfaz llamada IServer que deben implementar los servidores:
Obviamente en un caso real los métodos tendrían el algoritmo necesario para realizar tales operaciones. Hemos simplificado estos algoritmos y en su lugar realizamos una salida por consola en cada método.
Hasta aquí nada nuevo, sólo clases que implementan una interfaz y le dan inteligencia al método. Comenzaremos con el Command:
Ahora realizaremos un invocador, es decir, una clase que simplemente llame al método execute:
Veamos como funciona el ejemplo:
Consecuencias
- Command desacoplado: el objeto que invoca la operación de aquél que sabe como realizarla.
- Las órdenes son objetos manipulados y extendidos de forma natural.
- Se pueden ensamblar órdenes en una orden compuesta.
- Facilidad de adición de nuevos objetos Command.
3 comentarios:
podrias aclarar cual es el reciver, invoker y cliente en el ejemplo? aprobecho para felicitarte por tu blog. Me parece exelente.
Muchas Gracias
matias
Muchas gracias por tus comentarios Matias! El reciever es el target, es decir el objeto que se llama en el execute del command. En el ejemplo serian los servidores. El invocador es el que llama al command. Es quizas el objeto menos util de este patron. Fijate que hice una clase con ese nombre y su instancia la llame serverAdmin...solo para cumplir con el patron pero podrias obviarla tranquilamente! Saludos!
Muchas gracias necesitaba esto!!!
Publicar un comentario