¿ Eventos o señales ?
El sistema de eventos de ActionScript 3 ha sido objeto críticas en los últimos tiempos. Indudablemente es una de las piezas claves sobre las que se sustenta el desarrollo de aplicaciones Flex/Flash y de ahí su amplia utilización. A continuación resumiremos las más relevantes.
Los eventos.
Los eventos se identifican mediante un tipo de dato “String”, definido como una constante pública y estática, el mismo dato que se utiliza para registrar un manejador para ese evento. Eso implica que como desarrolladores debemos ser cuidadosos en escoger un valor que identifique de forma única al evento, de lo contrario podemos observar un comportamiento que no es el esperado en nuestras aplicaciones.
La semántica de este valor es otro elemento a tener en cuenta. Si estamos construyendo un API o un componente que será utilizado por otros desarrolladores es muy importante escoger un valor que exprese lo que representa el evento en sí, no solamente la palabra que representa la acción, sino también el tiempo verbal adecuado, para evitar confusiones acerca del momento en que se despacha el evento.
Si queremos crear eventos personalizados, que porten información relevante del contexto en el que los estamos utilizando tenemos que heredar de “Event”, no hay una interface IEvent o algo similar que permita que una clase del dominio pueda actuar como evento.
Una vez que hayamos heredado de “Event” debemos sobrescribir el método clone, para que cuando el despachador de eventos redespache el evento (en caso que sea necesario) obtenga una copia del evento original. Quiere esto decir que si en nuestra aplicación tenemos muchos eventos personalizados terminaremos escribiendo bastante código (aunque tenemos como alternativa utilizar la clase “DynamicEvent”, no se recomienda esta opción ya que no podremos hacer chequeo de tipos en tiempo de compilación y detectar errores de asignación, etc).
Los despachadores de eventos.
El método addEventListener, de la clase “EventDispatcher” tiene la siguiente definición:
El argumento “useWeakReference” es muy utilizado cuando se quiere que el mecanismo de recolección de basura elimine los objetos que contienen manejadores de eventos, pero como vemos es el último argumento en la lista. De modo que si frecuentemente utilizamos un valor “true” en este argumento y los valores por defecto en los argumentos “useCapture” y “priority”, el método se invocaría de la forma:
Al parecer, es común entre los desarrolladores invocar el método de esta forma, por lo cual se agradecería mucho que la lista de argumentos fuera:
En la clase “EventDispatcher” no existe un método que permita eliminar todos los manejadores de eventos de una sola vez.
Si se hereda de “EventDispatcher” a fin de crear un despachador personalizado y modificar su comportamiento, como un control personalizado de los manejadores de eventos, nos encontramos que no podemos acceder a la lista de manejadores, la clase tiene un diseño cerrado.
Por otra parte, aunque existe la interface “IEventDispatcher”, crear una clase que haga un tratamiento personalizado de los manejadores de eventos y que implemente la interface no funcionaría del todo, ya que la propiedad “target” de la clase “Event” es de solo lectura y solo la clase “EventDispatcher” es capaz de asignarle valor. De modo que la clase “Event” y “EventDispatcher” se diseñaron para trabajar juntas.
aS3-signals.
Existe un proyecto denominado as3-signals que plantea una alternativa al sistema de eventos de ActionScript 3 y que tiene en cuenta todos los inconvenientes anteriores. El proyecto está inspirado en el sistema de eventos de C# y en las signals/slots de Qt. La idea central es que en vez de tener un objeto (”EventDispatcher”) capaz de despachar cualquier tipo de evento a cuanto manejador se haya registrado, se utilizan objetos que contienen su propia lista de manejadores y cuya semántica representa un evento en específico. De esta forma el evento está identificado por el objeto en sí y no por un tipo de dato “String”, como ocurre en la clase “Event” y sus derivadas.
Un objeto “Signal” se define como un mini despachador específico para un solo evento, que contiene su propia lista de manejadores. Cuando se crea un objeto de este tipo se especifican los tipos de datos de los argumentos del método “dispatch”, que es el que invoca a los manejadores que se hayan registrado. De este modo el número de argumentos de los manejadores deben coincidir con los especificados en la creación del objeto.
Como funcionalidad distintiva tiene que permite eliminar todos los manejadores a una vez, a través del método “removeAll”, permite registrar un manejador que sea invocado una sola vez y luego automáticamente eliminado de la lista de manejadores, mediante el método “addOnce”, y permite conocer en cada momento la cantidad de manejadores registrados.
Básicamente el flujo de trabajo sería:
1. – Crear el objeto “Signal”:
O heredando de “Signal”
En este caso el objeto representaría si el usuario ha ingresado a la aplicación, sería el equivalente a
si estuviéramos utilizando un evento personalizado.
2. – Adicionar manejadores
O, si queremos que el manejador se invoque solamente una vez y sea eliminado de la lista automáticamente después de invocado:
La sintaxis del manejador quedaría:
3. – Despachar el evento
Cualquier intento de invocar el método “dispatch” con un argumento que no sea “Boolean” o con 0 o más de un argumento causará una excepción de tipo “ArgumentError”.
En el proyecto se incluyen cuatro tipos de “Signals”,
- “Signal”: Representa el comportamiento básico, que hemos descrito anteriormente.
- “DeluxeSignal”: Este tipo de “Signal”, a diferencia del anterior, permite asociar el evento a un objeto en particular, el que se pasa en el constructor; de modo que si el argumento del método “dispatch” es de tipo “IEvent”, encapsulará información del objeto asociado, y el propio objeto “DeluxeSignal”, la cual estará disponible en los manejadores. Permite además asignar prioridades a los manejadores.
- “NativeSignal”: Permite encapsular un evento nativo de ActionScript, el constructor toma como argumento un “EventDispatcher, un “String” que identifica el tipo del evento y un “Class” que identifica la clase del Evento (”Event” por defecto). Cuando se registra un manejador se registra en el “EventDispatcher”, el mismo que se utiliza para despachar los eventos. Todas las funcionalidades básicas, como eliminar todos los manejadores a la vez, registrar y despachar manejadores que se invocan una sola vez, etc., se ejecutan sobre el “EventDispatcher”. Permite también asignar prioridades a los manejadores. Esta clase da la posibilidad de un manejo homogéneo de eventos dentro de la aplicación.
- “NativeRelaySignal”: Ofrece las mismas funcionalidades que “NativeSignal”, pero se diferencia de ésta en que tiene su propio mecanismo para despachar eventos, no delega esta responsabilidad en el “EventDispatcher” que se pasa como argumento en el constructor, como sucede con “NativeSignal”.
Las “Signals” en el contexto de la Inversión de Control.
Normalmente cuando usamos el sistema de eventos de ActionScript el flujo de trabajo consiste en crear un evento (de la clase “Event”) asignándole su tipo en el constructor y despacharlo usando un “EventDispatcher”, ó en muchos casos, creando eventos personalizados (heredando de “Event”), asignar alguna carga útil y despacharlo. Constantemente estamos creando y despachando eventos.
El flujo de trabajo de las “Signals” hace que sea muy conveniente utilizarlas con frameworks que utilicen Inversión de Control, en este caso solo debemos crear el objeto “Signal” como un singleton en el framework (no es necesario implementar el patrón Singleton, solamente se debe indicar al framework que cree una sola instancia de la clase y que devuelva siempre la misma referencia), e inyectar la referencia en cuanto componente sea necesario (vistas, modelos, comandos, mediadores, etc.), de esta manera disminuiríamos notablemente la tarea de creación de objetos relacionada con los eventos, algo que siempre resulta costoso.
Conclusiones.
El proyecto as3-signals ofrece una alternativa interesante al sistema de eventos de ActionScript que podemos utilizar en nuestros proyectos y que puede beneficiarse del uso de frameworks de Inversión de Control.
Acerca de esta entrada
Usted está leyendo “¿ Eventos o señales ?,” una entrada de MadeInFlex
- Autor: Nono F. Carballo Escalona
- Publicada:
- 07.09.10 / 9am
- Categorías:
- Artículos
- Entradas relacionadas:
- Eventos
- Eventropia ¡rentabiliza al máximo la asistencia a tus eventos!
- AUG
- Oferta Laboral: emotique
- Número de visitas:
- 3381
7 Comentarios
Ir al formulario de comentarios | rss (comentarios) [?] | trackback url [?]