Arena - La importancia del binding

¿Qué pasa cuando nos olvidamos de diseñar al construir una UI?

Dentro del ejemplo del conversor, tenés otro ejemplo en SWT puro, donde no hay model, por lo tanto no hay binding. Señalamos algunas cosas interesantes:
  • En ese ejemplo no hay diseño: todo ocurre en la misma pantalla. No hay división de responsabilidades, ni "componentes" más allá de los controles visuales que definimos.
    • una consecuencia fácil de advertir es que el ejemplo en SWT necesita 100 líneas, mientras que el mismo ejemplo del conversor con Arena sumando las clases vista y modelo requiere 60. El factor de reducción aumenta cuando se empieza a agregar complejidad: el conversor sincronizado en SWT sube a 120 líneas, mientras que en la versión de Arena se conservan las 60 líneas originales (ya que al haber binding sólo es necesario reacomodar el control que hace la tarea delegando al setter correspondiente)
    • una clase que hace "todo" es evidentemente una clase poco cohesiva, una clase difícil de aprovechar en otro contexto y donde se tiende a copiar y pegar el código. Por ejemplo: en ningún lado queda registrado el número que representa el valor en kilómetros, sino que es una variable local que se crea (y luego descarta) dentro del listener del botón: 
 val button = new Button(panel, PUSH)
        button.text = "Convertir"
        button.HSpan = 4
        button.addListener(Selection, [ event |
            val selected = millasTextBox.text
            if (StringUtils.isBlank(selected)) {
                kmsValueLabel.text = ""
                status = "Ingrese millas a convertir."
            } 
            else {
                try {
                    val millas = Double.parseDouble(selected)
                    val kms = millas * 1.60934
                        
                    kmsValueLabel.text = new DecimalFormat("#.##").format(kms)
                    status = "Convertido !"
                }
                catch (NumberFormatException e) {
                    kmsValueLabel.text = ""
                    status = '''Error: «e.message»'''
                }
            }
        ])

    • Entonces, si en otra pantalla queremos poner un conversor, o manejar problemas de conversión de texto a números se nos va a complicar un poco así como lo tenemos armado. Si no queremos repetir las cosas (copiando y pegando), tenemos que aplicar las herramientas de diseño (llevando la conversión a un objeto que esté separado de la vista).
  • Si bien la idea de MVC está bastante difundida, a la hora de programar interfaces de usuario es muy común encontrar estos ejemplos como material didáctico y como forma de trabajo en las empresas. Al mercado todavía le cuesta mucho separar modelo de vista y trabajar el binding en forma bidireccional. Y ya hemos hablado que si mezclamos modelo con vista, 
    • mezclamos lo tecnológico y lo que no lo es
    • nos complicamos para hacer el testeo unitario, porque para poder probar la aplicación tenemos que probar todo (desde la perspectiva de usuario, mientras que la prueba unitaria puede automatizarse con facilidad sin depender de las cuestiones tecnológicas)
    • también perdemos la oportunidad de subclasificar temas que no tienen que ver entre sí: el modelo y la vista necesitan su propia jerarquía
    • en la solución de SWT hay más líneas, porque hay menos objetos. En los ejemplos de Arena aparecen muchos más objetos, eso paradójicamente permite bajar la cantidad de líneas de código.
    • en el ejemplo del conversor SWT la vista tiene como atributos (variables private) a los controles de SWT: 
    class ConversorSWT extends ApplicationWindow { 
        Label millasLabel 
        Text millasTextBox 
        Label kmsLabel 
        Label kmsValueLabel
    • y los quiere conocer porque no tiene modelo asociado. En cambio en la solución de Arena no necesitamos conocer a los controles, porque la vista conoce a su modelo y cada control tiene un binding, si nosotros modificamos el modelo el binding bidireccional nos asegura que todo funcione ok.
  • La forma de trabajo del ejemplo es más procedural, mientras que al trabajar con Arena logro un mayor grado de declaratividad, esto se traduce en
    • conozco menos de los detalles algorítmicos (entender dónde está el try/catch de la UserException lleva su tiempo), 
    • en la solución de SWT tengo más ocasiones donde "meter mano" (y quizás equivocarme) mientras que en Arena me concentro más en el qué, sin tener que resolver tanto el cómo (porque se lo delego a un "motor" que en este caso es el framework Arena + todos sus componentes: Commons Collections de Jakarta, SWT y JFaces)
    • como cada botón tiene su binding, también tiene menos importancia la idea de secuencia: es menos evidente el orden de ejecución del programa, el usuario es el que va disparando los mensajes.
    • tener menos control no siempre está bueno: hay bindings que no son posibles dependiendo de la versión de Arena que estemos usando (capturar el momento en el que el usuario sale del control o cambiarle el color no está disponible), por eso es bueno que el framework que usemos permita puntos de extensión para poder modificarlo desde afuera.
    • pero por otro lado no tener control puede ser bueno: en SWT es muy engorroso definir manualmente cada control que se cree para ubicarlo en la pantalla. En Arena en cambio eso es bastante más fácil, una vez que definimos el layout cada add del control en la pantalla va acomodando los controles solitos. 
Pueden descargarse otro ejemplo en el mismo proyecto donde está el Conversor.

Otros ejemplos "interesantes"