12 Command (Orden) Propósito Encapsula un mensaje como un objeto, permitiendo parametrizar los clientes con diferentes solicitudes, añadir a una cola las solicitudes y soportar funcionalidad deshacer/rehacer (undo/redo) Motivación Algunas veces es necesario enviar mensaje a un objeto sin conocer el selector del mensaje ni el objeto receptor. Por ejemplo widgets (botones, menús,..) realizan una acción como respuesta a la interacción del usuario, pero no se puede explicitar en su implementación.
13 Motivación Command
14 Estructura Command
15 Colaboración Command (Gp:) r : Receptor (Gp:) : Cliente (Gp:) co : Command (Gp:) : Invocador (Gp:) 1. Command (r) (Gp:) 2. registrarCommand(co) (Gp:) 1. ejecutar() (Gp:) 1.1. accion()
16 Command Aplicabilidad Parametrizar objetos por la acción a realizar (alternativa a funciones Callback: función que es registrada en el sistema para ser llamada más tarde; en C++ se puede usar punteros a funciones) Especificar, añadir a una cola y ejecutar mensajes en diferentes instantes: un objeto Command tiene un tiempo de vida independiente de la solicitud original. Soportar facilidad undo/redo. Recuperación de fallos.
17 Command Consecuencias Desacopla el objeto que invoca la operación del objeto que sabe cómo realizarla. Cada subclase CommandConcreto especifica un par receptor/acción, almacenando el receptor como un atributo e implementando el método ejecutar. Objetos command pueden ser manipulados como cualquier otro objeto. Se pueden crear command compuestos (aplicando el patrón Composite). Es fácil añadir nuevos commands. Un objeto Command es realmente un Adapter.
18 Command Implementación ¿Cuál debe ser la “inteligencia” de un command? No delegar en nadie Encontrar dinámicamente el objeto receptor y delegar en él Soportar undo/redo Atributos para almacenar estado y argumentos de la operación. Lista de objetos commands En la lista se colocan copias.
19 Mecanismo undo/redo
20 Mecanismo undo/redo public void invocarCommand (AbstractCommand command){ if (command instanceof Undo) { undo(); return; } if (command instanceof Redo) { redo(); return; } if (command.doIt()) { addToHistory(command); } else { historiaList.clear();} if (redoList.size() > 0) redoList.clear(); } private void undo() { if (historyList.size() > 0) { AbstractCommand ac; undoCmd = (AbstractCommand) historyList.removeFirst(); undoCmd.undoIt(); redoList.addFirst(undoCmd); }
21 Command En lenguajes como Eiffel o Java no es posible que un método pueda actuar como argumento de otro método. Por ello es necesario definir una clase (functor ) que encapsule al método y sus instancias se pasarán como argumento. Ejemplos en Java: Comparator, Observer, ActionListener, …
22 Ejemplos Functor Ejemplo 1: Comparar dos objetos utilizando cualquier criterio de ordenación: interfaz Comparator en Java
public interface Comparator { int compare (Object o1, Object o2); }
Un objeto Comparator puede ser pasado a una rutina de ordenación o ser utilizado por una colección para mantener el orden de sus elementos.
Ejemplo 2: Interfaz Observer en el patrón Observer.
Ejemplo 3: Interfaces listener en el modelo de delegación de eventos.
23 Ejemplo
24 Command Implementación Podemos evitar la jerarquía de subclases de Command si no necesitamos la facilidad undo/redo con metaclases. En Smalltalk,
self receptor perform: unSelector with: unArg
Un objeto functor normalmente implementa el comportamiento deseado sin delegar. Un objeto command normalmente delega en otro objeto. Un objeto command actúa como un functor si tan sólo implementa el comportamiento deseado.
25 Command Ejercicio: Escribir una clase con la funcionalidad de ejecutar periódicamente uno o más métodos sobre diferentes objetos. Por ejemplo, ejecutar una operación de copia de seguridad cada hora o una operación de comprobación de estado de un disco cada 10 minutos o imprimir la secuencia de Fibonacci. Se desea que la clase no conozca qué operaciones concretas debe ejecutar ni los objetos sobre los que debe aplicarlas. Esto es, se debe desacoplar la clase que planifica la ejecución de esos métodos de las clases que realmente proporcionan las operaciones a ejecutar.
26 Interpreter Propósito Dado un lenguaje, definir una representación para su gramática junto con un intérprete que utiliza la representación para interpretar sentencias en dicho lenguaje. Motivación Interpretar una expresión regular. Usa una clase para representar cada regla, los símbolos en la parte derecha son atributos. Aplicabilidad Usar si la gramática es simple y la eficiencia no es importante.
27 Intérprete expre := literal | cond | seq | rep alt := expre ‘|’ expre seq := expre ‘&’ expre rep := expre ‘*’ literal := ‘a’|’b’|’c’|…{‘a’|’b’|’c’|…| } *
28 Intérprete
29 Intérprete lluvias | (trasvase & desaladoras) *
30 Interpreter Estructura
Página anterior | Volver al principio del trabajo | Página siguiente |