Command

 
 
 
Clasificación Intención Otros nombres Motivación Aplicabilidad Estructura Participantes
Colaboraciones Consecuencias Implementación Código ejemplo Usos  Patrones Relacionados  Autores
 

Clasificación

Patrón de Diseño
 

Intención

Tener una interfaz abstracta de manejo de operaciones sobre cierto receptor, permitiendo a un cliente desarrollar las operaciones sin tener que conocer exactamente el tipo y realizar tareas de undo.
 

Otros nombres

Action, Transaction

Motivación

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.

Aplicabilidad

Utilice Command para: 
     
  • Parametrizar objetos por las acciones que realizan.
  • Especificar, administrar y ejecutar solicitudes en tiempos distintos. El objeto Command tiene un tiempo de vida que es independiente de la solicitud del comando que lo instancia.
  • Soporta la capacidad de deshacer la solicitud. el objeto Command puede guardar un estado que permita deshacer la ejecución del comando.
  • Soporta la capacidad de generar bitácoras que permitan la recuperación del estado en caso de que el sistema falle.
  • Permite estructurar un sistema en torno a operaciones de alto nivel construidas con base en operaciones primitivas o de bajo nivel.
 

Estructura

 

Participantes

Command 
     
  • Declara la interface para la ejecucion de la operacion
ConcreteCommand 
  • Define la relación entre el objeto Receiver y una acción
  • Implemeta Execute() al invocar las operaciones correspondientes en Receiver
Client 
  • Crea un objeto ConcreteCommand y lo relaciona con su Receiver
Invoker 
  • Le hace solicitudes al objeto Command
Receiver 
  • Sabe como ejecutar las operaciones asociadas a la solicitud. Cualquier clase puede ser receptora.

Colaboraciones

  • Un cliente crea un objeto ConcreteCommand.
  • El objeto Invoker guarda el objeto ConcreteCommand.
  • El objeto Invoker solicita al llamar Execute() de Command.
  • El objeto ConcreteCommand invoca las operaciones necesarias para resolver la solicitud.

Consecuencias

  1. Command desliga el objeto invocador del objeto receptor
  2. Los comandos son objetos de primera clase.
  3. Se pueden ensamblar comandos en comandos compuestos.
  4. Para un nuevo comando no se necesita extender las clases.

Implementación

  1. Que tan inteligente debe ser un comando: se debe considerar que un Command puede simplemente invocar a un receiver o puede realizar operaciones complejas que ningún otro objeto está en capacidad de realizar por si solo.
  2. Soporte a la opcion deshacer y rehacer: para implementar estas opciones el ConcreteCommand debe incluir información extra, pertinente al estado para así poder deshacer o rehacer una solicitud.
  3. Evite 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.
  4. Usar Templates de C++: Cuando los comandos no tiene opcion de deshacer y cuando no requieren argumentos, puede crearse un template de Command de la siguiente manera:

  5.  
     
    template <class Receiver>
    class SimpleCommand: public Command
    {
    public:
      typedef void (Receiver:: *Action) ();
      SimpleCommand( Receiver* r, Action a ) : _receiver(r), _action(a) 
      {};
      virtual void Execute( )
      {
        (_receiver->*_action)();
      };
    private:
      Action _action;
      Receiver* _receiver;
    };
     

Código ejemplo

Ejemplo que utiliza el Patron Command y el Patron Decorator 

Usos conocidos

Para la asignación de solicitudes en Menús y Botones, y cuando se requiera implementar la capacidad de deshacer solicitudes.

Patrones relacionados

COMPOSITE, MEMENTO, PROTOTYPE.
 
 

Autores

Walter Garcia, Gustavo Ospina