COMMAND
Propósito
Encapsula una petición como un objeto, lo que permite parametrizar los clientes con distintas peticiones, dejar en cola o registrar solicitudes, y soporta operaciones de deshacer.
También conocido como: Action, Transaction.
Motivación
Este patrón presenta una forma sencilla y versátil de implementar un sistema basado en comandos facilitándose su uso y ampliación, puesto que a veces se quiere poder enviar solicitudes a objetos sin conocer exactamente la operación solicitanda ni del receptor de la solicitud. En general un objeto botón o menú ejecuta solicitudes pero
la solicitud no está implementada dentro del mismo.
La clave de este patrón es una clase abstracta Command que define una operación execute. Son las subclases concretas quienes implementan la operación y especifican el receptor de la orden.
Aplicabilidad
Utilizamos el patrón Command cuando queremos:
- Parametrizar objetos para llevar a cabo acciones, sobretodo objetos MenuItem.
- Especificar, encolar, y ejecutar llamadas en diferentes momentos. Un objeto Comando puede tener una línea de vida independiente de la llamada original. Si el receptor del llamado puede ser representado como una dirección de espacio independiente, luego se puede transferir el objeto Comando para el llamado a un proceso diferente y realizar el llamado ahí.
- Soporte deshacer. La operación ejecutarComando( ) puede almacenar estados para revertir efectos en el propio comando. La interfaz debe tener una operación adicional (unExecute) que reversa el efecto de una llamada previa a ejecutar. Los comandos ejecutados están almacenados en una lista de historial.
- Soportar cambios en registro en las que se pueden reaplicar en caso de que el sistema colapse. Para agregar operaciones de cargar y guardar en la interfaz comando, se debe mantener un registro permanente de cambios. Recuperarse de un colapso requiere recargar los comandos de registro del disco y reejecutarlos con la operación ejecutar.
- Estructurar un sistema alrededor de operaciones de alto nivel construidas sobre operaciones primitivas ya que una estructura es común en los sistemas de información que soportan transacciones.
Estructura
Participantes
Command: Declara una interfaz para ejecutar una operación
ConcreteCommand: Define una relación entre un objeto Receivor y una acción. Implementa Execute() para invocar la respectiva acción en Receivor.
Client: Crea los objetos ConcreteCommand y su Receiver.
Invoker: Pregunta el comando para llevar a cabo la solicitud.
Receiver: Es la encargada de realizar operaciones asociadas con las peticiones de Execute(). Cualquier clase puede ser Receiver.
Colaboraciones
- El cliente crea un objeto ConcreteCommand y especifica su receptor.
- Un objeto Invoker guarda el objeto ConcreteCommand.
- El Invoker llama a Execute() en Command el cual esta implementado en ConcreteCommand.
- El objeto ConcreteCommand llama a las acciones pertinentes sobre su Receiver.
Consecuencias
- Command desacopla el objeto que invoca la operación que sabe cómo resolver.
- Command es la primera clase de objetos. Puede ser manipulada o extendida como cualquier otro objeto.
- Se puede ensamblar Command en un Composite Command (comando Compuesto).
- Es fácil adicionar nuevos Commands, porque no se tienen que cambiar las clases existentes.
Implementación
A la hora de implementar el patrón Command se debe tener en cuenta:
- ¿Qué tan inteligente debe ser un comando? Un comando puede tener una amplia gama de habilidades. En un extremo este se limita a definir un compromiso que vincula un receptor y las acciones que llevan a cabo la petición.
- Soporte de deshacer y rehacer. Command puede soportar deshacer y rehacer, si se dispone de una opción para revertir su ejecución. Una clase ConcreteCommand puede que necesite construir un estado adicional para haces esto.
- Evitar la acumulación de errores en el proceso de deshacer. En la medida en que se hacen y deshacen operaciones es posible que el estado al que se llega diverga del estado original de los objetos. Es necesario que el ConcreteCommand contenga suficiente información para que sea capaz de hacer que los objetos vuelvan al estado original.
- En C++ se pueden usar plantillas para representar Commands que no requieren argumentos ni se pueden deshacer
Usos conocidos
Las clases Button y MenuItem de Java:
- Facilitan la utilización de este patrón.
- Declaran los métodos getActionCommand y setActionCommand para dar nombres a las acciones realizadas por los objetos.
- Facilitan una correspondencia entre ambos.
Patrones relacionados
- Un Composite puede ser usado en la implementación de MacroCommands.
- Un Memento puede mantener el estado que requiere Command para deshaces sus efectos.
- Un Command que debe ser copiado antes de ser puesto en el historial de una lista actúa como un Prototype.
Referencias
- Design Patterns Elements of Reusable Object-Oriented Software, GoF.
No hay comentarios:
Publicar un comentario