10 enero 2018

¿Está vivo aún AngularJS 1.x?


En proyectos web, actualmente, en el mercado existen frameworks y/o apis para auxiliar en el desarrollo de aplicaciones web tipo SPA. Las cuales dan como resultado aplicativos visualmente más atractivos e interactivos con el Usuario. Utilizando  JavaScript como soporte y/o base en el desarrollo e implementación.

Uno de estos frameworks, que de alguna manera tenia sentido y/o futuro para el desarrollo del lado del cliente con JavaScript era AngularJS 1.x. Ya que es gratuito, Open Source y fue creado y mantenido por Google, por esta razón se hizo muy popular y todo mundo le invirtió en capacitación e implementación. Y en un parpadeo... pup; la nueva versión, por así decirlo, ya que no fue una mejora, básicamente es un nuevo framework. Angular (llamado también como Angular 2), no es compatible con versiones anteriores y no se proporciona soporte para realizar la migración.


Y la pregunta salio, ¿sigo desarrollando con AngularJS 1.x o me volteo y me capacito en Angular?

Y la respuesta, desde mi punto de vista, más allá de que es si eres nuevo en esto del desarrollo SPA, y decirte que te conviene meterte con Angular 2 o que si ya tienes experiencia con AngularJS 1.x siguieras por este camino. Tiene que ver con el enfoque y la arquitectura de tu aplicativo.

Es decir, si tu aplicativo va orientado a un entorno cliente servidor, en donde: las validaciones, reglas de negocio, por políticas o seguridad del cliente las proporciona el mismo servidor, como puede ser un Tomcat o un JBoss. Y la parte visual debe de ser rápida y eficiente desde el lado del cliente, basada en un entorno MVC. Entonces el enfoque debe de ser AngularJS 1.x.

Por otro lado, si tu aplicativo va orientado a un entorno cliente servidor, en donde: las validaciones, reglas de negocio son proporcionadas por un servidor js, como puede ser Node.js te conviene más Angular 2. Hay que mencionar que Angular 2 implementa TypeScript el cual es una extensión de JavaScript, por lo cual los componentes web son necesariamente compilados para ser ejecutados por los navegadores. Aunque también se puede realizar esta tarea escribiendo tu propio código plano con JavaScript, pero no es recomendable. Como nota, Angular esta orientado y pensado para móviles.

Otro punto a considerar es que AngularJS basa su arquitectura en MVC, mientras que Angular 2 se basa en servicios/controller, modificando el concepto de controlador presentado por AngularJS, permitiendo dividir al aplicativo en términos de componentes y no por eventos estándar del DOM que utiliza AngularJS.

Como nota, considera que un punto es que AngularJS se ejecuta desde el cliente, mientras que Angular 2, se ejecuta desde el servidor, ya que como comentamos es necesario ser compilado TypeScript.

Al final se tiene que AngularJS y Angular 2, son dos frameworks totalmente distintos, en arquitectura, forma de implementar y operar; que desde mi punto de vista, AngularJS todavia tiene camino por recorrer, ya que la comunidad es grande y aun lo podemos ver en desarrollos productivos y aun se tiene soporte.

Por lo pronto, al momento de publicar este post ya se tiene la versión de AngularJS 1.6.8, la cual fue publicada el 18 de diciembre del 2017.

06 febrero 2016

Polimorfismo - Java

La siguiente entrada la expongo a medida que es algo que en teoría lo deberías tener en mente, ya que es una de las bases a tener en la práctica al desarrollar. Sin embargo, esto en muchas veces no se implementa de la mejor forma o en el peor de los casos ni si quiera se implementa y te pierdes una de las grandes ventajas de la programación orientada a objetos, sin contar de las consecuencias al no hacerlo.

La palabra polimorfismo significa en griego "muchas formas", y eso es lo que buscamos en nuestro código; que el código que desarrollemos sea flexible en el sentido que los objetos instanciados se comporte de diferentes formas; tomando el lugar, forma o comportamiento de otro objetos de su mismo tipo.

Te preguntarás, ¿qué beneficios trae esto?. Como lo he venido comentando, uno de los principios al tener en mente al desarrollar, es siempre hacerlo de una forma abstracta y dejando las implementaciones a clases concretas. Esto nos permite al final el poder realizar ajustes al código de una forma fácil, ya que un cambio solicitado en el código se realiza en las sub-clases las cuales deberán de ser siempre sustituibles por sus clases padres dentro del código.

A continuación expongo un ejemplo, en donde tenemos un servicio Pintador, el cual tiene como objetivo el exponer un servicio el cual detalla como pintar algo. Posteriormente tenemos un par de clases concretas que extienden de esta interfaz. Para que finalmente dejemos un contexto que permita realizar o invocar los servicios de pintar a partir de las clases concretas.

Como nota: considere la clase ContextPintador en su método setPintador(Pintador pintador). Ya que es aquí en donde entra el polimorfismo (toma el lugar de una sub-clase de tipo Pintador) y el casting a su vez (el cual explicare en un post siguiente).

//Esta interfaz define el servicio de pintar; ¿qué?... no lo sabemos.
public interface Pintador {
   //regresa la instrucción de como pintar algo.
   public String doPinta();

}

//Esta clase sabe como pintar cuadros.
public class PintadorCuadros implements Pintador {
   @Override
   public String doPinta() {
      return "Regresando la instrucción de como pintar un Cuadro... :)";
   }

}

//Esta Clase sabe pintar casas.
public class PintadorCasas implements Pintador {
   @Override
   public String doPinta() {
      return "Regresando la instrucción de como pintar una Casa... :)";
   }

}

//Contexto que ejecuta la instrucción de como se debe de pintar
public class ContextPintador {

   private Pintador pintador;
   public ContextPintador() {
      super();
   }
   //Pasamos la referencia de una clase concreta, en este caso toma su comportamiento.
   public void setPintador(Pintador pintador) {
      this.pintador = pintador;
   }
  //Este método no sabe como se pinta algo, en realidad la clase
no sabe nada de como pintar algo, sin embargo le delega la
responsabilidad a la interfaz Pintador la cual opera como un sustituto y una referencia de una clase concreta;
en este caso toma el comportamiento de la operación doPinta().
   public void comoPintar() {
      if (pintador != null) {
System.out.println(pintador.doPinta());
      }
   }

   public static void main(String... args) {
      ContextPintador context = new ContextPintador();
//pasamos al contexto un pintador de casas
context.setPintador(new PintadorCasas());
context.comoPintar();
//pasamos al contexto un pintador de cuadros
context.setPintador(new PintadorCuadros());
context.comoPintar();
      }

}

Al ejecutar el código tenemos como respuesta el siguiente resultado:

Regresando la instrucción de como pintar una Casa... :)
Regresando la instrucción de como pintar un Cuadro... :)

Si después por necesidad tenemos que saber la dirección de la casa que se va a pintar, solo tenemos que modificar la sub-clase PintadorCasas y todo continua sin cambios significativos.

public class PintadorCasas implements Pintador {
private String direccion;
public PintadorCasas(String direccion) {
this.direccion = direccion;
}
@Override
public String doPinta() {
return "Regresando la instrucción de como pintar una Casa... en direccion: " + direccion;
}

} 

//modificamos la clase ContextPintador 
context.setPintador(new PintadorCasas("Calle 13 num 24"));

Y ejecutando de nuevo tenemos lo siguiente:

Regresando la instrucción de como pintar una Casa... en direccion: Calle 13 num 24
Regresando la instrucción de como pintar un Cuadro... :)

Como ven la clase ContextPintador no necesito cambios, a excepción del método main, y esto es lo importante, ya que ContextPintador trabaja con una clase abstracta, en este caso la interfaz Pintador, dejando que las clases concretas se especialicen en sus necesidades u objetivos.

NOTA: el polimorfismo se logra implementar por medio de la herencia, esta se puede realizar por medio de clases o de interfaces. En lo particular yo prefiero realizar la herencia, en la mayoría de los casos, de una interfaz que de una clase concreta, ya que la primera en general no cambia muy seguido sus operaciones.

Otra cosa, notar que la clase ContextPintador opera como un patrón de diseño... lo identificas?

23 enero 2016

Calidad en el diseño y/o programación de Sistemas.

Actualmente, en mi posición laboral, tengo que estar interactuando con muchos desarrolladores que están comenzando su carrera, así como experimentados. Y en la mayoría me encuentro con la poca calidad en el diseño y/o implementaciones de apis. Tengo que reconocer que suena engreído de mi parte el estar criticando el trabajo de otros, sin embargo, como punto a mi favor debo decir que no se necesita ser un experto para identificar un mal diseño. Para empezar debo de explicar desde mi punto de vista que es un buen diseño, que es esto, bueno: un buen sistema está bien diseñado si es fácil de comprender, leer o interpretar, fácil de modificar (sin que tenga de afectar miles de otras interfaces) y sobre todo fácil de reutilizar. ¿Fácil, no?, pues ¡no!, en la mayoría, como lo he comentado, me encuentro con todo lo contrario.

En esta entrada detallaré de forma breve los principios que debe de seguir un buena calidad en el diseño de sistemas.

En primer lugar me acurdo de un término utilizado en la universidad: diseño de hule, y como todo, poco después en la práctica entendí que significaba eso; desde mi perspectiva un mal diseño tiene código de hule aplicado por todas partes, el cual cuenta con las siguieres características:

  • Cuando dentro de un Sistema, al tratar de modificar un servicio se tiene que modificar otras interfaces o apis en cascadas para poder adaptar el nuevo cambio.
  • Cuando al realiza un cambio dentro del Sistema, este afecta en otros lugares desconocidos dentro del código.
  • Cuando no se puede fragmentar el código en servicios con la finalidad de reutilizarlo.
  • Por último, cuando se tiene repetición de mismos fragmentos del mismo  código en todos lados con una sola variante.
Si tu sistema cuenta con alguno de estos puntos, entonces califica como un mal diseño. ¿Y a que nos lleva esto? pues esto nos lleva a otro término utilizado en la jerga de la programación: código espagueti. Al estar dentro de este punto tu sistema no está del bien claro detallando un aspecto de una maraña de código poco claro y poco mantenible, rompiendo las ventajas que proporciona la programación orientada a objetos y sobre todo el polimorfismo. 

Para llevar un buen diseño dentro de tu sistema, este deberá de seguir los siguientes principios que sostiene la programación orientada a objetos.
  • Una clase no debe de gestionarse para realizar o resolver muchas cosas a la vez: cuando una clase conoce o da soporte para resolver más operaciones de las que debería, entonces deberás de pensar y dividir tu clase en operaciones más concretas.
  • Todo servicio deberá ser abierto para permitir su extensión, pero cerradas a la modificación: ¿qué dice? bueno suena un poco confuso pero tratare de explicarme. Tu sistema deberá de permitir el poder cambiar el entorno de un servicio en particular, sin cambiar el servicio en si. Y es aquí en donde entra una de las grandes promesas del polimorfismo. ver Wikipedia-Polimorfismo 
  • Las sub-clases deberán de ser sustituibles por sus clases padres: esto nos lleva a programar y a diseñar de una forma mas abstracta. De esta manera, las clases padre (interfaces) no deberían de conocer o proporcionar más información de lo que deberían. Dejando a las especializaciones a las sub clases. NOTA: como consejo de ser posible siempre que herede hágalo de una clase abstracta, en general las clases abstractas o interfaces cambian mucho menos que sus clases concretas. 
Siempre tenemos puntos a mejorar, desde mi punto de vista el desarrollar y diseñar sistemas de información tiene que ver con practica, mejora continua y sobre todo con las buenas practicas (esto incluyen los patrones de diseño). Pero todo lo anterior se tira a la basura si no se respeta lo antes mencionado ya que son las bases para una buena arquitectura. 

19 junio 2009

Patrones de Diseño

Como programadores diariamente estamos resolviendo problemas, a menudo, estos problemas los resolvemos de forma artesanal, no digo que este mal la forma de resolverlo, el problema esta en que invertimos tiempo en pensar en el “Como” lo resolveremos, además de que si queremos modificar o reutilizar este código, este se nos puede complicar porque nunca analizamos o diseñamos muy bien la solución del problema, y sumariza que si trabajamos en equipo, que es muy a menudo, tendremos que explicarle a nuestros compañeros como resolvimos nuestro problema.

Los patrones de diseño tratan la mayoria de estos problemas comunes que se nos presentan como programadores y que fuerón previamente resueltos, provados y documentados de forma exitosa por personas u organizaciones que anteriormente se enfrentarón a estos incovenientes.

En esta ocacion entraremos en el detalle de estos patrones de diseño, los cuales nos simplificaran la forma en el que crearemos y deseñaremos software. Los detalles de las implementaciones son llamadas estrategias.

El grupo de GoF clasificaron los patrones en 3 grandes categorías basadas en su PROPÓSITO: creacionales, estructurales y de comportamiento.


  • Creacionales: Patrones creacionales tratan con las formas de crear instancias de objetos. El objetivo de estos patrones es de abstraer el proceso de instanciación y ocultar los detalles de cómo los objetos son creados o inicializados.
  • Estructurales: Los patrones estructurales describen como las clases y objetos pueden ser combinados para formar grandes estructuras y proporcionar nuevas funcionalidades. Estos objetos adicionados pueden ser incluso objetos simples u objetos compuestos.
  • Comportamiento: Los patrones de comportamiento nos ayudan a definir la comunicación e iteración entre los objetos de un sistema. El propósito de este patrón es reducir el acoplamiento entre los objetos.
  • 25 diciembre 2006

    Por fin Luz v1.0 disponible


    Despues y de mucho especular por fin ve la luz el " Sistema Luz v1.0". Sistema de Gestión de Empleados, para la Agencia Comercializadora Prestadora de Servicios PRECOE.

    Este proyecto que originalmente se inicio hace como 1 añ o y medio, y que fue liberado a inicios del añ o 2006, pero con algunas, por no decir muchas fallas, pero fue remotado hace 3 meses para corregir estos errores y agregar mejoras.

    Este proyecto surguio como resultado de proyecto de tesis, con el fin de aprender y aplicar la tecnología java orientado a una aplicación stand-alone y que por fin y de muchos desvelos sale la versión estable, esta a disposición de cualquier persona en código fuente, desarrollado totalmente en java, utilizando como motor de base de datos MySQL 5.0.

    NOTA: Antes de continuar, quiero decir que este Sistema lo desarrolle completamente en java, cuando apenas no sabia nada, así que si observas el código notaras que la forma de programar es muy " inocente" , en cierto sentido y que en algunas otras es muy redundante, mi justificación es la de provar cual era la mejor forma de hacer las cosas y en realidad me he llevado varias sorpresas. (lo digo porque ya teniendo un poco de experienciay estudiar lo que hice al inicio veo y reconosco mis errores, pero no me arrepiento de haberlos hecho porque ya se como no se deben hacer las cosas, el problema radica en que me salto el diseñ o " vista-modelo-controlador" , solo en el último módulo en el de " configurar propiedades" lo hago y lo es ya que fue el último que hice dentro del sistema, pero no por eso el sistema deja de tener su chiste o su dificultad, y sus trucos)
    Primeramente descargaremos el fuente Luz
    v1.0



    También tendra que descargar el script de la creación de la base de datos Luz-db.sql
    Vea la documentación de Sistema Luz v1.0
    Dentro de las caracteristicas y mejoras que se hicierón son:
  • Manejo de roles

  • Altas, bajas y modificación de empleados

  • Busqueda de empleados

  • Impresión de información

  • Gestión de usuarios

  • Y mejoras en el fuente

  • Mas adelante continuae con detalles sobre la configuración e instalación
    del sistema, si tienes alguna duda o interes hasmelo saber.

    30 junio 2006

    Conectividad con la API JDBC

    La siguiente pequeña tutoría consiste en mostrar y enseñar
    lo que te piden en una entrevista de trabajo, como caso practico para evaluar
    el conocimiento que traes como programador.

    Básicamente te piden que realices una conexión con una base de datos
    ya sea en Oracle, MySQL o Server SQL, e inmediatamente te piden insertar, modificar,
    consultar y eliminar datos de algunas tablas.

    Bueno, empecemos de una vez, para terminar temprano, pero primero me imagino
    que querras ver el código fuente, asi que lo podras descargar de AQUI.


    PRIMER PASO: debemos de declarar algunas variables que nos serán útiles:

    private Connection conexion;// Representa la conexión con una BD.

    private Statement stmSql;//ejecutar una sentencia SQL

    private String sControlador; //Contiene el nombre del controlador.

    private String sUsuario;//Contiene el nombre de usuario.

    private String sContasenia;//contraseña para el acceso a la BD

    private String sURL;//Contiene el url para realizar la conexión

    private String sDB;//Nombre de la BD para trabajar

    De todas estas variables las mas importantes son la de Connexion , Statement, ya que en estas radican la funcionalidad de la conexión a la BD.


    SEGUNDO PASO: crear un constructor sin parámetros, que nos permitirá realizar una conectividad a una BD por default, el constructor de la clase le asignaremos, las rutas y/o parámetros que permitirán la conexión a la BD

    public Conexion(){

    sControlador = "com.mysql.jdbc.Driver";

    sDB = "dbluz";

    sUrl = "jdbc:mysql://localhost/"+sDB;

    sUsuario = "root";

    sContrasenia = "moster03";

    }

    Observe como la variable sControlador se le asigna el nombre del controlador, en este caso la conexión se realiza con MySQL, el nombre cambia dependiendo
    de la BD a conectarse, se puede configurar una conexión especificando
    la clase del driver y la URL de la conexión para la base de datos seleccionada.
    Abajo tiene un listado con las clases de driver, las URLs de conexión
    y los ficheros .jar del driver para las bases de datos más utilizadas:


    DB2

    Clase Driver : COM.ibm.db2.jdbc.app.DB2Driver

    URL de Conexión:: jdbc:db2:<database>

    Fichero .jar/.zip: db2java.zip

    Sybase

    Clase Driver : com.sybase.jdbc2.jdbc.SybDriver

    URL de Conexión:
    dbc:sybase:Tds:<host>:<port>/<database>

    Fichero .jar/.zip: jconn2.jar

    Oracle

    Clase Driver : oracle.jdbc.driver.OracleDriver

    URL de Conexión: jdbc:oracle:thin:@ <host>:<port>:<sid>

    Fichero .jar/.zip: classes12.zip

    SQLServer

    Clase Driver : com.microsoft.jdbc.sqlserver.SQLServerDriver

    URL de Conexión: jdbc:microsoft:sqlserver://localhost:1433

    Fichero .jar/.zip: mssqlserver.jar, msbase.jar, msutil.jar

    PostgreSQL

    Clase Driver: org.postgresql.Driver

    URL de Conexión: jdbc:postgresql://<server>:<port>/<database>

    Fichero .jar/.zip: postgresql.jar


    NOTA:

    • Los drivers o conectores para la JDBC generalmente son ofrecidos por
    las mismas empresas que ofrecen los servicios de las BD, por ejemplo MySQL la
    ofrece en el siguiente dominio: http://www.mysql.com/products/connector/j/

    TERCER PASO: Crear otro constructor que realice la conexión a la BD,
    nótese que dependiendo de la información que le enviemos, este
    constructor nos permitirá realizar la conexión con cualquier BD.

    public Conexion(String sControlador, String sDB, String sUsuario,

    String sContrasenia, String sUrl){

    this.sControlador = sControlador;

    this.sUsuario = sUsuario;

    this.sContrasenia = sContrasenia;

    this.sUrl = sUrl+sDB;

    }

    Dependiendo de la funcionalidad de tu código, tu eliges que tipo de
    constructor elegir, si tu sabes que tipo de BD utilizar y no cambia utiliza
    la primera, si por el contrario tu necesitas estarte conectando en varias BD
    como Oracle o Serverr SQL y no estés creando clases para realizar las
    conexiones para cada una te recomiendo la segunda.

    CUARTO PASO: el siguiente paso es crear un método que nos permita abrir
    la conexión a la BD.

    private void vodAbrirConexion(){

    try{

    Class.forName(sControlador).newInstance();

    conexion = DriverManager.getConnection(sUrl,sUsuario,sContrasenia);

    stmSql = conexion.createStatement();

    System.out.println("Conexion Creada con Exito '_'");





    Este método es muy importante ya que en este crearemos las instancias
    correspondientes para realizar la conexión.

    Nótese como en el método pasado se invoca al método forName
    de Class que devuelve una Clase, especificada con el controlador, garantizando
    un objeto de la clase del controlador. En seguida creamos una instancia de la
    clase Connection por medio de la clase DriverManager que obtiene la conexión
    por medio del método getConnection con los atributos de la url de la
    BD, el nombre del usuario de la BD y por ultimo la contraseña del usuario,
    que administra la BD, creamos otra instancia de la clase Statement en base a
    la instancia Connection antes creada por su método createStatement, esta
    instancia de Statement es con la que estaremos interactuando hasta que se cierre
    la conexión a la BD para realizar las distintas sentencias SQL. Finalmente
    creamos las excepciones que nos permitirán verificar que se halla realizado
    con eficacia la conexión.

    QUINTO PASO: creamos un método que nos permita cerrar la BD.

    public void vCerrarConexion(){

    try{

    if(stmSql!=null){

    stmSql.close();

    ….

    }

    if(conexion!=null){

    conexion.close();

    ……

    }

    }

    catch(SQLException eSQL){/*NO HACER NADA*/}

    }

    Nótese como cerramos tanto el objeto de Statement como el objeto de Connection.

    SEXTO PASO: finalmente creamos un método que nos permitirá ejecutar
    sentencias SQL, impactando en la BD ya sea para Seleccionar, Borrar, etc.

    Como se observa el siguiente método nos permitirá ejecutar sentencias.

    private ResultSet rstSetConsulta(String sConsultaSql){

    ResultSet rsConsulta = null;

    try{

    rsConsulta = stmSql.executeQuery(sConsultaSql);

    }

    ….

    Observe que esta función nos regresa un objeto de tipo ResultSet, así
    como recibir como parámetro una consulta sql, que será procesada
    por el método executeQuery, de la clase Statement.

    SEPTIMO PASO: Finalmente nos queda crear un método que nos permita ejecutar
    actualizaciones en la Base de Datos, ya sea un insert, update o delete.

    private void vodModificar(String sIntruccionSQL){

    try{

    stmSql.executeUpdate(sIntruccionSQL);



    FINAL. Finalmente nos queda más que jugar con estos métodos y
    hacer nuestras consultas o actualizaciones en la base de datos tan complejas
    como se nos sea posible en base a nuestros objetivos dentro del sistema.

    Si observa en la clase Conexión.java, se crea un método llamado
    executaConsulta, que utiliza al método rstSetConsulta, y este realizar
    la consulta en especifico, dándole un tratamiento especial a los valores
    obtenidos, no importando si es de tipo int, String float, etc, ya que son obtenidos
    como Objetos, finalmente son pasados a una variable de tipo StringBuffer, pudiéndose
    también pasar en un Vector, una lista, arreglo, etc. Notese que ademas
    nos traen los metadatos es decir los nombres de los campos en la Base de datos.

    En el main, se realizan las pruebas pertinentes, si observa solo invocamos
    a la clase y en esta invocamos metos y/o funciones pasándole solamente
    las sentencias SQL, correspondientes y estos se encargan de lo demás,
    haciendo la transacción a la BD mas fácil.

    26 junio 2006

    Que es AJAX?

    Buscando nuevas técnologias para el desarrollo web me he encontrado con un articulo bastante bueno que introduce un nuevo término, que para mi es nuevo, y fastante interesante AJAX.


    ¿Porque es tan interesante AJAX? Porque en realidad AJAX no es una tecnología, sino la unión de varias tecnologías que juntas pueden lograr cosas realmente impresionantes como GoogleMaps , Gmail el Outlook Web Access ( ref ) o algunas otras aplicaciones muy conocidas: AJAX , en resúmen, es el acrónimo para Asynchronous JavaScript + XML y el concepto es: Cargar y renderizar una página, luego mantenerse en esa página mientras scripts y rutinas van al servidor buscando, en background, los datos que son usados para actualizar la página solo re-renderizando la página y mostrando u ocultando porciones de la misma.


    La traducción completa a continuación:


    Ajax : Un Nuevo acercamiento a las Aplicaciones Web

    Por Jesse James Garret t

    February 18, 2005


    Si algo del actual diseño de interacción puede ser llamado glamoroso, es crear Aplicaciones Web. Después de todo, ¿cuando fue la ultima vez que escuchaste a alguien hablar de diseño de interacción de un producto que no esté en la Web? (Okay, dejando de lado el iPod). Todos los nuevos proyectos cool e innovadores están online.


    Dejando de lado esto, los diseñadores de interacción Web no pueden evitar sentirse envidiosos de nuestros colegas que crean software de escritorio. Las aplicaciones de escritorio tienen una riqueza y respuesta que parecía fuera del alcance en Internet. La misma simplicidad que ha permitido la rápida proliferación de la Web también crea una brecha entre las experiencias que podemos proveer y las experiencias que los usuarios pueden lograr de las aplicaciones de escritorio.


    Esa brecha se está cerrando. Hechenle una mirada a las Google Suggest. Mira la forma en que los términos sugeridos se van actualizando a medida que uno tipea casi instantáneamente. Ahora mire Google Maps. Hace zoom. Usen el cursor para agarrar el mapa y navegarlo un poco. Otra vez, todo sucede casi instantáneamente, sin esperar que las paginas se recarguen.


    Google Suggest y Google Maps son dos ejemplos de un nuevo acercamiento a las aplicaciones Web, que nosotros en Adaptative Path hemos denominado AJAX . El nombre es una abreviación o acrónimo para Asynchronous JavaScript + XML, y ello representa un cambio fundamental en que es posible en la Web.


    Definiendo Ajax

    Ajax no es una tecnología. Es realmente muchas tecnologías, cada una floreciendo por su propio mérito, uniéndose en poderosas nuevas formas. AJAX incorpora:


    • presentación basada en estándares usando XHTML y CSS;

    • exhibición e interacción dinámicas usando el Document Object Model ;

    • Intercambio y manipulación de datos usando XML and XSLT ;

    • Recuperación de datos asincrónica usando XMLHttpRequest ;

    • y JavaScript poniendo todo junto.


    El modelo clásico de aplicaciones Web funciona de esta forma: La mayoría de las acciones del usuario en la interfaz disparan un requerimiento HTTP al servidor web. El servidor efectúa un proceso (recopila información, procesa números, hablando con varios sistemas propietarios), y le devuelve una pagina HTLM al cliente. Este es un modelo adaptado del uso original de la Web como un medio hipertextual, pero como fans de “The Elements of User Experience” sabemos, lo que hace a la Web buena para el hipertexto, no la hace necesariamente buena para las aplicaciones de software.


    figura 1

    Figura 1: El modelo tradicional para las aplicaciones Web (izq.) comparado con el modelo de AJAX (der.).


    Este acercamiento tiene mucho sentido a nivel técnico, pero no lo tiene para una gran experiencia de usuario. Mientras el servidor esta haciendo lo suyo, que esta haciendo el usuario? Exacto, esperando. Y, en cada paso de la tarea, el usuario espera por mas.


    Obviamente, si estuviéramos diseñando la Web desde cero para aplicaciones, no querríamos hacer esperar a los usuarios. Una vez que la interfaz esta cargada, porque la interacción del usuario debería detenerse cada vez que la aplicación necesita algo del servidor? De hecho, porque debería el usuario ver la aplicación yendo al servidor?


    Como es diferente AJAX

    Una aplicación AJAX elimina la naturaleza “arrancar-frenar- arrancar-frenar” de la interacción en la Web introduciendo un intermediario -un motor AJAX - entre el usuario y el servidor. Parecería que sumar una capa a la aplicación la haría menos reactiva, pero la verdad es lo contrario.


    En vez de cargar un pagina Web, al inicio de la sesión, el navegador carga al motor AJAX (escrito en JavaScript y usualmente “sacado” en un frame oculto). Este motor es el responsable por renderizar la interfaz que el usuario ve y por comunicarse con el servidor en nombre del usuario. El motor AJAX permite que la interacción del usuario con la aplicación suceda asincrónicamente (independientemente de la comunicación con el servidor). Así el usuario nunca estará mirando una ventana en blanco del navegador y un icono de reloj de arena esperando a que el servidor haga algo.


    Figura 2

    Figura 2: El patrón de interacción sincrónica de una aplicación Web tradicional (arriba) comparada con el patrón asincrónico de una aplicación AJAX (abajo).


    Cada acción de un usuario que normalmente generaría un requerimiento HTTP toma la forma de un llamado JavaScript al motor AJAX en vez de ese requerimiento. Cualquier respuesta a una acción del usuario que no requiera una viaje de vuelta al servidor (como una simple validación de datos, edición de datos en memoria, incluso algo de navegación) es manejado por su cuenta. Si el motor necesita algo del servidor para responder (sea enviando datos para procesar, cargar código adicional, o recuperando nuevos datos) hace esos pedidos asincrónicamente, usualmente usando XML, sin frenar la interacción del usuario con la aplicación.


    Quien está usando Ajax

    Google está haciendo una significativa inversión en el acercamiento Ajax. Todos los grandes productos que Google ha introducido en el ultimo año (Orkut, Gmail, la última versión de Google Groups, Google Suggest, y Google Maps ) son aplicaciones Ajax. (Para datos más técnicos de estas implementaciones Ajax, lean estos excelentes análisis de Gmail, Google Suggest, y Google Maps.) Otros están siguiendo la tendencia: muchas de las funciones que la gente ama en Flickr dependen de Ajax , y el motor de búsqueda de Amazon A9.com aplica tecnologías similares.


    Estos proyectos demuestran que Ajax no es solo técnicamente importante, sino también prácticos para aplicaciones en el mundo real. Esta no es otra tecnología que solo trabaja en un laboratorio. Y las aplicaciones Ajax pueden ser de cualquier tamaño, de lo más simple, funciones simples como Google Suggest a las muy complejas y sofisticadas como Google Maps.


    En Adaptive Path, estuvimos haciendo nuestro propio trabajo con Ajax en los últimos meses, y estamos descubriendo que solo raspamos la superficie de la rica interacción y respuesta que que las aplicaciones Ajax puede proveer. Ajax es un desarrollo importante para las aplicaciones Web, y su importancia solo va a crecer. Y como hay tantos desarrolladores que ya conocen como usar estas tecnologías, esperamos ver mas empresas y organizaciones siguiendo el liderazgo de Google en explotar la ventaja competitiva que Ajax provee.


    Mirando adelante

    Los mayores desafíos al crear aplicaciones Ajax no son técnicas. Las tecnologías centrales son maduras, estables y bien conocidas. En cambio, los desafíos son para los diseñadores de estas aplicaciones: olvidar lo que creemos saber sobre las limitaciones de la Web, y comenzar a imaginar un rango más amplio y rico de posibilidades.

    Va a ser divertido.