Patrón de Diseño Observer en Xojo

Patrón Observer en XojoEn esta entrada veremos cómo implementar el patrón de diseño Observer, y las ventajas que nos proporciona frente a otros enfoques; además de que lo veremos de una forma práctica, a través de un ejemplo.

En una entrada anterior ya vimos como podíamos implementar el patrón de diseño Singleton en nuestras aplicaciones Xojo, así como las ventajas que aportaba su uso en una programación OOP, tal y como permite nuestro lenguaje de programación multiplataforma favorito.

¿Por qué utilizar el patrón de diseño Observer? Pongamos por caso una aplicación que consta de una serie de elementos Canvas que hacen la función de parches de color, de modo que estos cambien de forma aleatoria cada vez que pulsamos un botón. ¿Cómo lo harías? Una de las posibles formas —es probable que hayas pensado en ella— es recorrer todos los elementos Canvas e indicar que se vuelvan a redibujar nuevamente invocando el método Refresh. Es válido, pero ciertamente no orientado a objetos y un tanto estricto.

Otro enfoque más versátil es mediante la implementación del patrón de diseño Observer. Este patrón de diseño consiste en que un objeto informará de que se ha producido una acción para la cual se han registrado todos aquellos objetos interesados en recibirla; y, ¿sabes qué? algunos de los controles gráficos incluidos de serie en el Framework de Xojo ya incorporan este patrón (mediante la implementación de interfaces de clase). Puedes ver todas ellas en este enlace, si bien para nuestro primer ejemplo nos centraremos en ActionSource y ActionNotificationReceiver, utilizados por ejemplo en los controles BevelButton, PushButton, así como la clase Timer. ¿No te parece genial contar con la capacidad, por ejemplo, de que varios objetos sean notificados cada vez que se dispare un temporizador?

ActionSource y ActionNotificationReceiver en la práctica

Pero sigamos con nuestro ejemplo inicial, y por ahora lo haremos utilizando las interfaces disponibles de serie en el framework de Xojo para ver la forma más simple de implementar el patrón de diseño Observer con lo que ya tenemos por omisión.

Para ponerlo en práctica, crea un nuevo proyecto de tipo Desktop. A continuación, y desde la Librería arrastra el icono correspondiente a la clase Canvas sobre el Navegador del Proyecto (esta acción creará una entrada con el nombre CustomCanvas).

Selecciona el elemento CustomCanvas y, en el panel Inspector, pulsa sobre el botón Interfaces. Dicha acción desplegará la hoja en la que podremos seleccionar todas las interfaces de clase que desemos implementar en esta clase personalizada. Marca la casilla de verificación correspondiente a actionNotificationReceiver. Es decir, nuestra clase “es un” (IsA) Canvas y también es un ‘actionNotificationReceiver’.

Una vez confirmada la selección y cerrada la hoja de interfaces, se habrá añadido el método PerformAction a nuestra clase “CustomCanvas”, puesto que forma parte de la interface definida por actionNotificationReceiver. De hecho, este será el método que invocará el objeto con el que nos registremos. Por tanto incluye el siguiente código como parte del método PerformAction:

me.Refresh

Sencillo, ¿verdad? Lo cierto es que será el propio evento Paint del propio Canvas (invocado cada vez que se llama al método Refresh) el encargado de ejecutar el código que nos interesa en nuestro ejemplo; es decir, cambiar su color por cualquier otro de forma aleatoria. Para ello, añade el evento Paint a nuestra clase CustomCanvas (Insert > Event) y escribe el siguiente código:

dim r as new Random
g.ForeColor = rgb(r.InRange(0,255),r.InRange(0,255),r.InRange(0,255))
g.FillRect(0,0,g.Width,g.Height)

Ya hemos terminado con nuestra clase personalizada, es el momento de crear la interfaz de usuario. Arrastra el elemento CustomCanvas desde el Navegador de Proyecto sobre la ventana, con ello habremos creado una instancia (sinónimo de objeto) a partir de nuestra clase, basada a su vez en la clase Canvas.

Ahora bien, en nuestro ejemplo hemos indicado que necesitamos varios “parches” de color… de modo que lo más sencillo es crear un Control Set. Piensa en ello como un grupo de controles del mismo tipo que comparten el mismo comportamiento, y a los que podemos acceder desde el código a través de su índice (o posición) que ocupan dentro del grupo.

Para crear un Control Set, selecciona la instancia de nuestro CustomCanvas en la ventana del Editor de Diseño y accede a la pestaña de Atributos del panel Inspector, tal y como muestra la siguiente imagen:

Creación de Control Set en Xojo

Selecciona el menú desplegable “Member Of” y elige la opción “New Control Set”. Al hacerlo se creará el grupo “CustomCanvas1” y asignará el índice “0” al objeto seleccionado.

Ahora duplica el control cuatro veces y alinéalos uno al lado del anterior respetando los márgenes propuestos por el IDE de Xojo. Observarás que cada control tiene ahora su propio índice dentro del mismo grupo y que el Navegador de Proyecto tendrá el siguiente aspecto, mostrando este hecho de forma jerárquica:

Jerarquía de Control Set en Xojo

La interfaz de usuario debería de tener un aspecto similar a este:

Interfaz de usuario en tutorial de ejemplo

Para completar nuestra interfaz de usuario solo nos queda utilizar un “disparador”, y en este caso utilizaremos un PushButton que implementa por omisión el modelo “ActionSource-ActionNotificationReceiver” (es decir, una implementación del patrón Observer).

Patrón Observer en acción

Por último sólo nos queda registrar en nuestro Observer (el control PushButton) aquellos objetos que deseamos que sean notificados para que ejecuten su acción asociada cada vez que el usuario pulse sobre el botón, ¡y aquí es donde agradeceremos haberlos reunido bajo un único Control Set para simplificarlo aun más!

Selecciona el elemento etiquetado “CustomCanvas1 Set” en el Navegador de proyecto. Es decir, la entrada que agrupa todos los miembros del grupo, y no la selección de cualquiera de sus miembros.

Ahora añade el evento Open (Insert > Event) e introduce el siguiente código:

PushButton1.addActionNotificationReceiver me

Con ello habremos registrado todos los miembros del grupo como objetos interesados en recibir la notificación.

Ejecuta la aplicación y pulsa sobre el PushButton, comprobarás que cada vez que lo hagas… ¡todos los canvas cambiarán su color!

Resultado final de tutorial Patrón Observer

De esta forma, hemos visto de qué modo tan sencillo y con qué poco código hemos conseguido nuestro objetivo. De hecho, el PushButton añadido al proyecto no cuenta con código alguno. Lo mejor de todo es que mantenemos el código compatimentado y fácil de mantener y ampliar sin que afecte al resto de nuestra aplicación. Incluso si modifcásemos el número de miembros CustomCanvas en tiempo de ejecución, la aplicación continuaría funcionando correctamente.

Recuerda que en mi libro electrónico “Programación Multiplataforma Xojo” te explico desde cero todo lo que necesitas saber para coger las riendas del lenguaje desde cero, y que no te sientas perdido con ninguno de los términos utilizados en este tutorial.

En la siguiente entrega puedes ver como  crear e implementar nuestras propias interfaces para implementar el Patrón de Diseño Observer de formas algo más flexibles (por ejemplo, que el objeto registrado pueda recibir parámetros).

5 comentarios en “Patrón de Diseño Observer en Xojo

  1. azrak

    Muy fácil de implementar, lastima xojo tiene poca salida profesional.

    una pregunta : Se puede meter todo el código en una classe (fichero) como en Java en vez de ir añadiendo métodos y propiedades con el ide ?

    1. Javier Rodriguez

      Hola,

      Xojo tiene mucha salida profesional. De hecho se utiliza tanto para la creación de soluciones verticales (software empresarial) como en desarrollos propios (aparte de la oferta de proyectos a la que se puede acceder en el foro de Xojo, siempre que tengas licencia Pro). Son muchas las aplicaciones creadas con Xojo que han sido destacadas, por ejemplo, en las listas de la App Store o que se venden como software comercial.

      Sobre tu consulta, actualmente el IDE de Xojo no contempla dicha posibilidad. En el foro de Xojo se debate de cuando en cuando esto mismo… y las conclusiones siempre suelen ser las mismas: precisamente una de las fortalezas del entorno es el modo en el que se hace ahora mismo, y no se ve muy bien las ventajas que aportaría hacerlo tal y como indicas. Aun así, quizá en un futuro IDE (ya se anunció el año pasado que se estaba trabajando en ello) pueda implementarse dicha capacidad.

  2. Patrones de Diseño: Observer (y II) - AprendeXojo

    […] de diseño Singleton y también de qué modo tan práctico encontramos el patrón de diseño Observer implementado en las características incluidas de serie en Xojo. En esta entrada pondremos todo […]

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *