Similitudes entre React y Polymer con Apache Tapestry

Escrito por el .
java opinion planeta-codigo tapestry
Enlace permanente Comentarios

React y Polymer son dos librerías JavaScript para construir interfaces complejas en el lado cliente basadas en componentes. Los componentes son interesantes porque hace que el código sea reutilizable, fácil de entender y más fácil de modificar sin introducir errores entre otras cosas. Aunque en el desarrollo web en el lado del servidor la mayoría de los frameworks se basan en acciones también hay algunos que se basan en componentes, uno de ellos Apache Tapestry para la plataforma Java. Si de React y Polymer se está hablando bastante bien y forman parte del actual estado del arte JavaScript, si la gente conociese y usase Tapestry que tiene varias similitudes con ellos creo que también les facilitaría el desarrollo de aplicaciones web pequeñas o grandes, simples o complejas en la parte del servidor.

Apache Tapestry

La librería JavaScript ReactJS es una de las que más se está hablando para bien y utilizando para construir aplicaciones complejas en el navegador. Personalmente después de haberla probado en el ejemplo lista de tareas con React y Backbone me ha parecido que está muy bien. Otra de las librerías que suele mencionarse y que en un futuro puede emplearse mucho más es Polymer. ¿Cuál es el éxito de estas librerías?

Uno de los motivos en mi opinión es que ambas se basan en un concepto de componente, en React un componente encapsula su estado o propiedades y eventos que maneja junto con la plantilla para generar las etiquetas de su interfaz gráfica, Polymer va un poco más allá y además de estado, eventos y plantilla encapsula los estilos CSS. Pero estas librerías que sirven para crear interfaces en el lado del cliente basadas en componentes y que se están viendo como algo bueno, en el lado del servidor la mayoría de los frameworks se basan en acciones, sin embargo, también hay algunos basados en componentes, uno de ellos es Apache Tapestry en la plataforma Java.

El concepto de componente de estos frameworks JavaScript o el utilizado en Tapestry no es nuevo quizá tiene otro nombre y es similar a lo que en los lenguajes de programación orientados a objetos conocemos como clases o tipos y en alguna asignatura también podemos haber aprendido como TAD. Básicamente cualquiera de ellos trata de agrupar en una entidad los datos (propiedades) y las funciones que los manejan (métodos) haciendo que el estado sea siempre válido manipulable solo a través de su interfaz, proporcionan una abstracción para que baste conocer la interfaz y no su funcionamiento interno. Y esto es bueno, ya que hace que sean muy fácil de usar, de reutilizar componentes ya probados, menor acoplamiento, que además redunda en un mantenimiento más sencillo y productividad, además, se pueden construir componentes complejos a partir de componentes más sencillos. El éxito de los extendidos lenguajes orientados a objetos se debe en gran medida a estos importantes conceptos.

Un componente React y otro de Polymer tienen el siguiente aspecto en código.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
var TareaComponent = React.createClass({
    componentDidMount: function() {
        var _this = this;
        this.ui = {
            completada: $('input[name=completada]', this.getDOMNode())
        };
        
        this.ui.completada.change(function(event) {
            _this.props.tarea.toogle();
            _this.props.tarea.save();
        });
    },      
    render: function() {
//          return (
//              <label className="checkbox">
//                  <input type="checkbox" name="completada" checked={(this.props.tarea.get('completada'))?'checked':''}/> <span className={this.props.tarea.completada}>{this.props.tarea.get('descripcion')}</span>
//              </label>
//          );
        return React.DOM.label({className:'checkbox'},
            React.DOM.input({type:'checkbox', name:'completada', checked:(this.props.tarea.get('completada'))?'checked':''}),
            React.DOM.span({className:this.props.tarea.completada}, this.props.tarea.get('descripcion'))
        );
    }
});
react.js
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
<polymer-element name="age-slider">
  <template>
    This is <b>{{owner}}</b>'s age-slider.
    <b>{{name}}</b> lets me borrow it.
    He likes the color <span style="color: {{color}}">{{color}}</span>.
    I am <b>{{age}}</b> years old.
    <p><label for="ageInput">Age:</label>
    <input id="ageInput" type="range"
           value="{{age}}">
    <label for="nameInput">Name:</label>
    <input id="nameInput" value="{{name}}"
           placeholder="Enter name..."></p>
  </template>
  <script>
    Polymer({
      age: 25,
      name: "Daniel",
      color: "red",
      owner: "Eric",
      nameChanged: function() {
        if (this.name) {
          // Ensure name is capitalized
          this.name = this.name[0].toUpperCase() +
                      this.name.slice(1);
        }
      }
    });
</script>
</polymer-element>
polymer.html

Uno de los motivos que comentaba para elegir Tapestry era precisamente este de componente. En Tapestry un componente está formado por una clase Java que contiene la lógica del componente tanto para obtener los datos que necesite la plantilla como para manejar los eventos que se produzcan en el navegador como clics o envío de formularios con datos, también puede tener asociada una plantilla que generará el HTML que se enviará al navegador web del cliente y que usará la clase Java para obtener los datos que necesite de forma pull en vez de push (el modelo push es el habitual en los frameworks basados en acciones), puede necesitar algunos archivos JavaScript para añadir algún comportamiento en el cliente y finalmente archivos de estilos CSS. El componente define los archivos JavaScript y de estilos que necesita y Tapestry se encarga de incluirlos en la página cuando se genera. Solo se incluyen los necesarios según los componentes que se hayan usado para generar la página, no haciendo falta incluir archivos de forma global.

Para usar un componente en Tapestry basta con conocer sus parámetros y los eventos que puede lanzar, estos forman su interfaz que nos abstraen de su funcionamiento interno. Por supuesto su pueden crear componentes más complejos a partir de otros más simples como si de piezas lego se tratase.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
package es.com.blogspot.elblogdepicodev.plugintapestry.components;

import org.apache.tapestry5.annotations.Property;
import org.apache.tapestry5.ioc.annotations.Inject;

import es.com.blogspot.elblogdepicodev.plugintapestry.services.dao.ProductoDAO;

public class NumeroProductos {

    @Inject
    ProductoDAO dao;

    @Property
    Long numero;

    void beginRender() {
        numero = dao.countAll();
    }
}
NumeroProductos.java
1
2
3
4
<!DOCTYPE html>
<t:container xmlns="http://www.w3.org/1999/xhtml" xmlns:t="http://tapestry.apache.org/schema/tapestry_5_4.xsd" xmlns:p="tapestry:parameter">
    Hay ${numero} productos.
</t:container>
NumeroProductos.tml

Según lo que comenta la gente parece bastante entusiasmada cuando prueban React o Polymer y considero que si les gusta el concepto de componentes en el lado del cliente creo que también les gustaría el concepto de componentes en el servidor que proporciona Apache Tapestry (entre otras muchas cosas que proporciona) si lo conociesen y probasen. Y son herramientas totalmente compatibles porque perfectamente se puede usar Tapestry en el lado del servidor y React o Polymer en el lado del cliente.

Hace meses escribí un libro sobre Apache Tapestry que puedes descargar completo y gratuitamente para conocer más detalles sobre este framework para la plataforma Java. Si aún necesitas conocer más también escribí un artículo comentando muchas de las varias características más destacables de Tapestry. Por supuesto puedes consultar más artículos etiquetados como tapestry en esta bitácora y en El blog de pico.dev.

Portada libro: PlugIn Tapestry

Libro PlugIn Tapestry

Si te interesa Apache Tapestry descarga gratis el libro de más de 300 páginas que he escrito sobre este framework en el formato que prefieras, PlugIn Tapestry: Desarrollo de aplicaciones y páginas web con Apache Tapestry, y el código de ejemplo asociado. En el libro comento detalladamente muchos aspectos que son necesarios en una aplicación web como persistencia, pruebas unitarias y de integración, inicio rápido, seguridad, formularios, internacionalización (i18n) y localización (l10n), AJAX, ... y como abordarlos usando Apache Tapestry.



Comparte el artículo: