- El Pensadero de Canek - https://aztlan.fciencias.unam.mx/pensadero -

Model-View-Controller

En ingeniería de software hay un patrón de desarrollo que se llama MVC, por Model-View-Controller. La idea es que tenemos cierta información (el modelo), y que tenemos cierta forma de representarla (la vista), y que son independientes y, hasta cierto punto, ortogonales: de hecho en teoría debemos ser capaces de “conectar” distintas vistas al mismo modelo, y todo debe ser transparente y bonito.

¿Para qué sirve esto? Básicamente para que no se nos haga bolas el engrudo respecto a los datos que estamos trabajando y cómo se los presentamos al usuario. En el momento en que en el mismo camino de código estamos lidiando con información y con cómo la representamos, no estamos lejos de meternos en problemas.

Tal vez la parte más importante del patrón MVC es la famosa C; el controlador. Cómo hacemos para que (de forma inmediata, y automágica) la vista se actualice cuando los datos en el modelo son modificados, o que si el usuario cambia algo en su vista, los datos en el modelo cambien también. Si estamos utilizando encapsulamiento de datos la cosa puede complicarse porque la vista tiene que hablarle al modelo, y el modelo a la vista, y aunque no es raro que la vista cargue una referencia al modelo, sí es horrible que el modelo cargue una referencia a la vista… especialmente si ya dijimos que en teoría deberíamos poder conectarle distintos tipos de vistas.

Cómo solucionamos este pequeño problema depende de muchas cosas: el lenguaje de programación, la biblioteca que estemos utilizando para hacer la interfaz gráfica, el paradigma que estemos usando (en C o Scheme podemos usar Orientación a Objetos, por ejemplo), etc., etc. Yo de lo que quiero hablar es de cómo suele solucionarse en C utilizando Gtk+.

Como muchos usuarios únicamente esporádicos de Gtk+, no había querido meterme a aprender a usar el TreeView; cuando los mismos desarrolladores de Gtk+ dicen que es complejo, a uno no le dan muchas ganas de meterse en problemas usándolo. Pero para una nueva versión de mi programita en PyGtk que muestra y baja los últimos trailers en la página de Apple, decidí que lo que tenía que usar era el TreeView, y me puse a estudiar para aprender a usarlo.

Está bien bonito; de verdad no entiendo por qué tantos dicen que es complejo: está bien fácil de usar. Claro, a lo mejor está relacionado con que yo estoy familiarizado con el patrón MVC: el TreeView es un ejemplo de libro de texto de aplicación de dicho patrón. Pero lo que me sorprendió aún más fue cómo resolvieron el problema de la comunicación entre la vista y el modelo; no sólo por lo elegante y bonito de dicha solución, sino además porque era rete obvio y a mí nunca se me había ocurrido.

GObject (y por tanto, Gtk+) ofrece un marco de trabajo orientado a objetos en C; incluyendo herencia, despacho dinámico, interfaces, etc. Pero además también ofrece un sistema de señales: cada objeto en GObject puede emitir señales en determinadas circunstancias, y uno puede conectar funciones (llamadas generalmente callbacks) a cada señal que se emita.

Esto se usa en la mayoría de los casos para manejar los eventos generados por la interfaz gráfica: cuando uno hace clic en un botón en Gtk+, el objeto del botón emite la señal “clicked”, y entonces uno puede conectarle una función a dicha señal para que haga lo que sea que haya que hacer cuando el usuario haga clic en dicho botón.

Pero las señales están disponibles a todos los objetos de GObject; entonces el TreeView lo que hace es que los modelos que utiliza implementan la interfaz TreeModel, que define ciertas señales a las cuales se conecta el TreeView. La idea es que cuando el modelo modifique sus datos se dispare una señal, a la cual el TreeView se habrá conectado, y entonces sabrá cuándo (y cómo) modificar la vista.

Y ya está; se preserva el encapsulamiento de datos, y se cumple al pie de la letra el patrón MVC.

La verdad no sé cómo no había pensado yo en eso; en Geom se me hizo un montón de bolas el engrudo, y terminé dejando en la misma clase todo lo relacionado con el modelo (la información geométrica) y la vista (cómo dibujarlo en mi lienzo). No tengo que explicar que eso hizo que todo se me hiciera un relajo después de un tiempo.

Para mi programita que baja los trailers del sitio de Apple hice eso; puse en clases independientes (que heredan de PyGObject) todo el código que va a la página y se conecta y baja la información, y señales para cada paso del camino: una señal cuando baja el poster, otra señal cuando obtiene el URL del video, etc. Y entonces la interfaz gráfica sólo se conectaba a esas señales y sabía cuándo tenía que hacer algo. Quedó bastante padre.

Con este nuevo truco me están dando ganas de volver a programar en Geom. Lástima que esté tan ocupado ahorita.

Imprimir entrada [1] Imprimir entrada [1]