Jun 06

Tipado fuerte y débil, dinámico y estático.

error tipado de datosTodo esto del tipado en los lenguajes de programación es algo que más o menos creía tener claro y que seguramente es lo más básico de cualquier carrera de informática actual, pero yo ya tengo mis añitos, no he estudiado estas cosas y al buscar lenguajes para aprender, he visto que hay una sutil diferencia entre estático/dinámico y fuerte/débil. Vamos a ello.

Estático vs Dinámico

En un lenguaje con tipado estático, las variables llevan asociado el tipo de dato y no se puede cambiar. En los lenguajes de tipado dinámico, el tipo va más bien asociado al valor de la variable y no a la variable en sí misma, por lo que una misma variable puede contener a lo largo de la ejecución distintos tipos de datos.

Con tipado estático, es el mismo compilador el que comprueba que se asignan valores correctos a las variables, ya que sabe de qué tipo son las variables y qué tipo de valores pueden admitir. 

Con tipado dinámico, esta comprobación debe hacerse en tiempo de ejecución. Podemos meter en cualquier variable cualquier tipo de dato, por lo que hasta la ejecución no se sabe qué tipo de valor tiene una variable.

La ventaja del tipado estático es que se pueden evitar muchos errores en tiempo de compilación, sin necesidad de esperar a la ejecución para verlos. La ventaja del tipado dinámico es su flexibilidad.

Fuerte vs Débil

No parece haber un consenso claro de lo que es fuertemente tipado y débilmente tipado, pero parece que la idea más general es si el lenguaje permite cambiar unos tipos por otros de forma más o menos automática o no lo permite, salvo quizás de forma explícita. Me explico.

En javascript podemos hacer esto sin problemas

var a=3;
var b="4";
var c=a+b;

es decir, guardamos un entero en a, una cadena en b y luego las sumamos. Javascript, sin consultar con nadie, hace una conversión del entero 3 en cadena "3" y suma las cadenas, dando como resultado en c la cadena "34". 

En java, también podemos hacer algo parecido

int a = 3;
String b = "4";
String c = a+b;

dando como resultado una cadena "34"

Vemos que ambos lenguajes son débilmente tipados (entre comillas), pero java es estáticamente tipado ya que es necesario declarar los tipos de las variables, y javascript es dinámicamente tipado, ya que no es necesario.

La afirmación de que ambos son "débilmente tipados", hay que tomarla entre comillas. Javascript es más débilmente tipado porque siempre intenta hacer las conversiones necesarias para que el código se ejecute sin problemas, aunque a veces los resultados son sorprendentes. Java en este caso de sumar entero y String es débilmente tipado, pero solo para cositas muy concretas. Convierte tipos a String cuando lo necesita, pero poco más. Por ejemplo, en javascript todo esto es válido

if ("0"==0)  // es true
if ("0")  // es true
if ("") // es false
if ("3"==3) // es true

es decir, convierte String a integer para hacer las comparaciones, convierte "" en false en el tercer caso, etc, etc. Java daría error con cualquiera de estos if, por lo que no es tan débilmente tipado como javascript.

La ventaja de un lenguaje dinámicamente tipado es evidente, ahorra muchas conversiones explícitas que en algunos casos pueden ser muy tediosas. Sin embargo, la pega es que requiere un conocimiento profundo de cómo se hacen esas conversiones, o podemos encontrarnos con errores inesperados al realizarse alguna conversión que no esperamos.

May 30

Autocompletar en los IDE

autocompletar en javascriptPara trabajar siempre me gustan más los lenguajes estáticamente tipados que los dinámicamente tipados y entre otras ventajas, una de ellas es la de autocompletar de los IDE. Pero siempre que digo esto, alguien me comenta que si el IDE está correctamente configurado, los dinámicamente tipados también tienen autocompletar.

Bien, esto es cierto, pero sólo parcialmente. Imagina el siguiente trozo de código en un lenguaje estáticamente tipado, como java

public void metodo ( UnaClase parametro) {
   parametro.???
}

Cuando empezamos a teclear en la zona de ???, el IDE sabe que parámetro es de tipo UnaClase, porque se ve claramente, así que es perfectamente capaz de darnos los métodos y atributos públicos de parámetro para que elijamos uno.

Sin embargo, en un lenguaje dinámicamente tipado, si tenemos el código equivalente

function unaFuncion (parametro) {
   parametro.???
}

aquí el IDE no tiene ni idea de qué tipo es parámetro y de hecho, no puede saberlo, porque parámetro puede ser de cualquier tipo cuando el código se esté ejecutando, se puede llamar a unaFuncion() pasándole un entero, una cadena de texto, un objeto propio que hayamos creado o cualquier otro tipo que se nos ocurra. Así que el IDE aquí es totalmente incapaz de ofrecernos opciones, salvo que el lenguaje tenga algo común en todos sus tipos.

¿Cómo se apaña entonces para autocompletar?. Bien, un caso como el que acabamos de mostrar es imposible, pero los IDEs tienen sus trucos para ofrecernos opciones de autocompletar cuando es posible. Por ejemplo, en el caso anterior, si tenemos

function unaFuncion (parametro) {
   parametro.funcion1();
   parametro.funcion2();
   var a = parametro.atributo1;
   parametro.???
}

aquí el IDE ve qué cosas usamos de parámetro, así que cuando lleguemos a los ??? nos ofrecerá las funciones y atributos que ya hemos usado (funcion1, funcion2, atributo1), sean o no correctos y de hecho, pueden no ser correctos porque nos hemos equivocado al teclear o simplemente porque en tiempo de ejecución alguien nos pasa como parámetro algo que no tenga esas funciones ni atributos.

Otro truco usado por los IDE es el siguiente

function unaFuncion () {
   var b = new UnaClase()
   b.???
}

en este caso, se ve claramente qué contiene la variable b, aunque no tenga tipo definido, ya que estamos haciendo un new de una clase concreta y metiéndola en la variable. Si el IDE es capaz de encontrar en nuestro código la definición de UnaClase, será capaz de ofrecernos sus métodos/funciones y atributos … es justo el caso de la imagen.

Así que sí, los IDE pueden autocompletar en lenguajes dinámicamente tipados, pero con ciertas limitaciones.

Nov 30

Sobre angularjs

Porque me ha tocado en el curro, me he leído AngularJS by Brad Green and Shyam Seshadri y he empezado a trabajar con AngularJS. Aprovecho aquí para comentar el libro y los conceptos básicos de angularJS.

El libro

El libro no me ha hecho demasiada gracia. Los dos primeros capítulos sí me gustaron, muy sencillos y explican lo más básico de angularJS. Sin embargo, a partir del tercer capítulo, la cosa se complica y no me parece que hayan conseguido explicarla bien. Empiezan a meter mucho código con muchas de las cosas propias de angular sin dar una explicación detallada de ellas, por lo que aunque intuyes de que va el tema o cómo funciona, los detalles no te quedan claros. Imagino que con la práctica me acabe enterando.

Los conceptos

angularJS es un framework MVC javascript mantenido por google. Ya estamos con los "palabros", vamos a intentar explicarlo.

En angularJS el modelo no es más que una variable javascript llamada $scope en la que se añaden de la forma normal en javascript todos los datos (modelo) que queramos.

La vista es un HTML en el que podemos poner algunas cosas específicas de angularJS. Por ejemplo, un párrafo podría ser <p>{{unaVariable}}</p> done unaVariable es un atributo de $scope, es decir, $scope.unaVariable existe y es lo que se pondrá dentro de los tags <p> y </p>. Una característica interesante de angularJS es que esta relación es bidireccional y automática, de forma que si nuestro código javascript modifica el valor de la variable, automáticamente se refleja en la vista HTML, y si ese {{unaVariable}} lo pusieramos en un input text así <input type="text" ng-model="unaVariable">, en cuanto el usuario teclea se actualiza la variable.

El controlador es una clase javascript en cuyo constructor recibe el $scope (y otras cosas) y se encarga de rellenarlo con los datos que necesitemos. También a esa clase le ponemos todas las funciones javascript que necesitemos y a las que se podrán llamar desde los distintos eventos de HTML (onclick, submit, etc).

Por supuesto, podemos hacer un HTML principal (index.html o similar) que dentro llevará varias vistas, cada una con su propio modelo y controlador. La idea es hacer una aplicación de simple página e ir reemplazando dentro de ella los distintos trozos HTML según el usuario vaya pulsando botones y menús.

Aparte de este concepto MVC, angularJS tiene una serie de utilidades que resuelven los problemas típicos en cualquier aplicación web. Veamos los más importantes

Directivas : En angularJS podemos definir nuestras propias directivas, aparte de las que angularJS ya nos proporciona. Una directiva es una forma de reemplazar un tag a atributo de un tag html por lo que  nosotros queramos. Un ejemplo tonto sería hacer una directiva "horaActual", de forma que si en nuestro HTML ponemos <horaActual></horaActual> se reemplazará por la fecha/hora actual (porque así lo hemos codificado en la directiva). Por supuesto, el código que hay que hacer es más sencillo que andar buscando los tags HTML y reemplazándolos a pelo.

Servicios : En angularJS podemos definir servicios, que simplemente son código javascript realizado por nosotros con determinadas funciones que queremos poder aprovechar en varios sitios. Si creamos un servicio con una serie de funciones javascript, angularJS podrá pasarlo como parámetro en el constructor de los controladores, de forma que estos tendrán disponible y podrán usar las funciones javascript de nuestro servicio. Es bastante habitual hacer que los servicios sean los que hablen con el servidor, para pedirle información que debe presentarse al usuario, o enviarle las operaciones que ha realizado el usuario.

Promises : Relacionado con los Servicios cuando estos hacen llamadas al servidor, tenemos las Promises. Si el usuario hace una operación que necesita enviar y esperar respuesta del servidor, normalmente llamará a una función javascript de uno de nuestros servicios. Este función hará la llamada al servidor (con AJAX por ejemplo) y recibirá de forma asíncrona el resultado. Pues bien, nuestra función javascript del servicio puede devolver inmediatamente, sin esperar el resultado, una de estas Promises, que no es más que una instancia de una clase javascript de angularJS, y cuando tenga el resultado llamar al método resolve() de la Promise. angularJS se enterará y actualizará el modelo cuando el resultado esté disponible (hayamos llamado a resolve). Un pequeño ejemplo lo dejará más claro

function pideDatosAlServidor (…, $q) {     // $q es un objeto específico que nos pasará angularJS para trabajar con Promises
   var defer = $q.defer();            // Obtenemos un objeto deferred para manejar nuestra Promise
   $.get ("url", function (data) {          // Nuestra llamada a ajax. AngularJS tiene parte de jQuery embebido.
       // hacemos algo con los datos recibidos
      defer.resolve();                      // Indicamos que ya se dispone de los resultados.
   }
   return defer.promise;             // Devolvemos la Promise
}

Fíjate que la llamada a $.get() es una llamada AJAX que llamará a function(data) cuando se tengan los resultados. El código pideDatos() hace esta llamada y directamente, sin esperar el resultado, devuelve el defer.promise. Esto le bastará a angularJS para saber que tiene que esperar por los datos antes de refrescar la página.

Test : AngularJS está pensado para que se puedan hacer test unitarios y de integración, por lo que viene con herramientas como e2e (end to end), facilitando, con herramientas adicionales, incluso cosas como levantar un servidor para los test y ejecutarlos.

Por supuesto, angularJS tiene otro montón de cosillas típicas para ayudarnos en nuestro desarrollo, como facilidades para la internacionalización, validación de formularios, bucles en las plantillas HTML, filtros, etc, etc.

Bueno, me he quejado de que el libro no explica bien, y escribiendo esto veo que es difícil explicarlo bien, pero al menos no  he necesitado 175 páginas.

Mar 29

He leído “JavaScript, The Definitive Guide”

Hace un mes aproximadamente terminé de leer "JavaScript, The Definitive Guide". Un libro sobre JavaScript y alrededores que me ha encantado. Aparte de JavaScript, trata bastante bien temas como JavaScript en un navegador web, una introducción a node.js y rhino en el lado del servidor, AJAX, jQuery, almacenamiento local en el navegador, Canvas de HTML5, …

Son un montón de páginas, 1100 nada menos, pero aproximadamente la segunda mitad son una guía de referencia de las funciones de JavaScript, por lo que de lectura es aproximadamente la mitad.

Comienza con los principios de programación en JavaScript desde cero, el típica capítulo de introducción al lenguaje que no aporta demasiado a casi nadie, demasiado rápido para el que no sabe nada de programación, pero demasiado trivial para el que sabe programar en otros lenguajes. Aun así, dentro de esta parte, he encontrado una pequeña joya para alguien como yo acostumbrado a otros lenguajes y es todo el tema de cómo se hacen conversiones de tipos automáticas, sobre todo en los condicionales, es decir, cuándo una variable independientemente de su tipo (string, numérico, un objeto,…) se considera que es true o false.

Sin embargo, luego empieza a meterse en profundidad en montones de temas variados de JavaScript y aquí es donde algún programador experto en otro lenguaje pero sin demasiado conocimiento de JavaScript, empieza a disfrutar del libro. Por supuesto, hay temas demasiado farragosos como para que sea agradable leerlos, pero hay otros que me han parecido geniales, tanto por lo que supone aprender cosas que no sabes, como por la forma de exponerlas.

Entre los primeros, los farragosos, está la parte de orientación a objetos en JavaScript, clases, herencias, polimorfismo a base de tipado tipo pato, También la parte de eventos en los navegadores web es pesadita, más que nada porque cada navegador es de su padre y de su madre y no hay acuerdo en los eventos que se producen, cómo se llaman y cuándo se producen. El libro no puede hacer mucho más que dar una lista con una breve descricpción de cada uno de ellos.

Sin embargo, entre las partes geniales, me ha encantado la forma de explicar las expresiones regulares, tanto, que he hecho mi propio tutorial de expresiones regulares en JavaScript siguiendo esa forma de explicación, por supuesto, donde esté el libro que se quite cualquier tontería que haya podido hacer yo. También me ha encantado la forma de explicar jQuery, todos sus apartados, desde los selectores para buscar y modificar elementos de nuestro HTML, como la parte de AJAX, efectos especiales como fadeIn() y fadeOut(), …

En fin, totalmente recomendado para aquel que ya ha empezado a programar cosas en JavaScript pero necesita profundizar y comprender más el tema.

Jan 09

“Duck Typing”

En un lenguaje fuertemente tipado y orientado a objetos, se comprueban las clases de los objetos antes de asignarlos a variables, de forma que sólo se pueden asignar a una variable objetos que son de la misma clase que la variable o hijas de la misma. Por ejemplo, si la clase Hija herada de la clase Padre, se puede hacer esto

Padre p = new Hija();

Una vez hecho, sólo pueden llamarse a métodos o atributos que estén declarados en la clase Padre. Si Padre tiene metodo1() e hija tiene metodo2(), sólo podemos hacer p.metodo1(), mientras que p.metodo2() dará error. Todo esto da sentido a cosas como las interfaces, definiendo a priori que métodos necesitan tener las clases hijas para que luego estas lo implementen.

Hay otros lenguajes, como javascript, que usan lo que se llama "Duck typing" o como lo traduzco yo "tipado tipo pato". La idea básica de este tipado es que si algo anda como un pato, grazna como un pato y nada como un pato, pues entonces es un pato. Los lenguajes que usan este tipado no miran los tipos ni las herencias de los objetos, simplemente permiten asignar cualquier cosa a cualquier variable. De esta forma, podemos hacer

p = new Hija();

y luego llamar tranquilamente a p.metodo1() o p.metodo2(), pero también podemos hacer

p = new Padre();

y llamar a p.metodo1(), dando error p.metodo2(). Es decir, no importa el tipo, el error saltará a la hora de hacer la llamada si "el pato no es capaz de granzar".

 

Mar 13

Extraños errores de javascript con Firefox y OpenLayers

 Estamos (seguimos) haciendo un mapa con geoserver en el lado del servidor y OpenLayers en el lado del navegador. Todo va más o menos de perlas dentro de lo que cabe en cualquier proyecto software, hasta que un cliente nos lanza la incidencia de que no puede ver el mapa con Firefox. Revisando veo que el mapa se ve perfectamente con Chrome, con Internet Explorer y con las versiones viejas de Firefox, pero no con las nuevas (de la 7 hacia arriba).

Saco la consola de errores y encuentro errores tan extraños como estos OpenLayers.Class is not a function, OpenLayers.Geometry is undefined, …

Por supuesto, no es problema de carga de librerías javascript, con otros navegadores funciona bien y no aparecen errores 404 de ficheros .js no encontrados.

Aunque desconcertante inicialmente, la solución fue sencilla. Hay algún tipo de incompatibiidad entre la versión de Openlayers que estaba usando (una del año pasado) y la interpretación de javascript de los firefox nuevos. No me he metido a ver cual era exactamente el motivo, pero bastó con actualizar la versión de OpenLayers a la más moderna.

Jan 26

Más de JSTL: core_rt y obtener el locale fijado con fmt:setLocale

Bueno, sigo jugando con JSTL. Un par de cosillas que he descubierto estos días.

JSTL core_rt

En el post anterior mencionaba una posible forma de acceder a las constantes de un bean desde jstl. Otra forma es, en vez de usar el JSTL core, usar el JSTL core_rt, que está pensado para no usar las expresion EL típicas de JSTL core como ${variable}, sino para usar y tener acceso a las mismas variables y expresiones de los scriptlets que van entre <% … %>

Con JSTL core haríamos algo como

<jsp:useBean id="bean" class="com.chuidiang.UnaClase"></jsp:useBean>

<c:out value="${bean.UNA_CONSTANTE}" />

y que requería del método getUNA_CONSTANTE() en el bean UnaClase

Pues bien, otra opción para esto es usar core_rt

<%@ taglib uri="http://java.sun.com/jstl/core_rt" prefix="c_rt"%>

y esto nos permitiría hacer directamente

<c_rt:out value="<%= UnaClase.UNA_CONSTANTE %>"/>

donde hemos podido usar un normalito <%= …. %>

Con core_rt tenemos todos los tags de core, con la diferencia de que usaremos <%= …%> en vez ${ …. }

Obtener el locale fijado con fmt:setLocale

Otro de los grupos de tags de JSTL es para la internacionalización (i18n que dicen ahora, ya que entre la i y la n de "internacionalización" hay 18 letras). Importando la taglib adecuada

<%@ taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="fmt"%>

A partir de ahí tenemos fmt:setBundle para indicar dónde están nuestros ficheros de propiedades con los textos en los distintos idiomas, fmt:message que nos permite mostrar textos al usuario según el idioma seleccionado (por defecto el del navegador) y fmt:setLocale si queremos un idioma distinto del navegador (por ejemplo, para ofrecer al usuario que lo solicita otro idioma distinto). Hay más tag para formateo de fechas y números de acuerdo al idioma elegido.

Pero echo en falta de menos un fmt:getLocale. Si cambiamos el locale con fmt:setLocale, no hay forma simple de saber más adelante cual hemos puesto. Pero sí la hay, un poco rebuscada. Si hacemos este cambio

<fmt:setLocale value="en_UK"/>

el scope por defecto es page y podemos obtener el locale con

<c:out value="${pageScope[‘javax.servlet.jsp.jstl.fmt.locale.page’]}"/>

y si lo cambiamos con scope="session" para que afecte a todas las páginas en la sesión

<fmt:setLocale value="en_UK" scope="session"/>

se puede obtener más adelante o en otra página con

c:out value="${sessionScope[‘javax.servlet.jsp.jstl.fmt.locale.session’]}"/>

¿Y para qué es útil esto?. Pues no lo tengo claro, pero comento para qué me ha hecho falta. La aplicación también tiene javascript y también tiene textos en los javascript (por ejemplo, en las ventanas confirm() o alert() antes de borrar algo). Para internacionalizar javascript suele ser necesario incluir algún fichero .js con los textos. También es habitual que haya un fichero distinto para cada lenguaje, por ejemplo es.js, en.js, etc. Y claro, no vamos a incluir todos estos ficheros en nuestra página, sólo deberíamos incluir el necesario para la visualización concreta que estemos haciendo. Pues una forma de conseguirlo es hacer la inclusión de esta manera

<script src=’path/<c:out value="es.js"/>’  …. ></script>

por supuesto, sin poner es.js a piñón fijo, sino obteniéndolo con el pequeño chorizo anterior. Quedaría tan feo como esto

<script src=’path/<c:out value="${sessionScope[‘javax.servlet.jsp.jstl.fmt.locale.session’]}.js"/>’ ….></script>

 Eso sí, tampoco es tan simple, ya que si no hemos hecho un fmt:setLocale, ese valor no existe y es null. Tenemos que recoger entonces el locale de ${pageContext.request.locale}, que es donde está el locale del navegador. Así que nos tocará hacer un if ….

Dec 15

Clases y herencia con javascript

 Por la necesidad de organizar un poco el código de javascript, que va creciendo y creciendo de forma desordenada y desmesurada en nuestro proyecto, me he puesto a mirar un poco el tema de objetos y herencias, también como organizar esas clases en lo que en java se llaman paquetes, no sé si en javascript se llaman namespaces, o ni siquiera existe nombre para eso.

Me ha llamado la atención que las clases realmente son las funciones. Cualquier función que declaremos en javascript es una clase y se puede hacer un new de ella. La función en sí misma se convierte en el constructor de la clase y las "cosas" que definamos en esa función como this.cosa=…. se convierte en atributo o método de esa clase, según sea una variable u otra función.

La herencia es un poco rara, sobre todo cuando buscamos en internet en que hay 49 formas de hacerla y alguna más. Al final, lo más sencillo y mínimo imprescindible es hacer algo como ClaseHija.prototype = new ClasePadre; Ya está la herencia hecha.

Si el constructor Padre tiene parámetros (la función Padre tiene parámetros), podemos llamarla desde el constructor del Hijo (la función Hijo) usando call() tal que así Padre.call(this,parametros), esa sería la forma de que el constructor hijo llame al padre pasándole cosas.

Finalmente, para agrupar las clases en "paquetes" o como quiera que se llame en javascript, basta con hacer el típico 

paquete = {
   Padre : function(…) {….},
   Hijo : function(…) {…}
}

a = new paquete.Hijo;

En fin, lenguaje demoníaco por un lado, pero me está gustando por otro. Mas detalles de lo aprendido en la chuwiki.

Dec 08

Jugando con jQuery

Ahora que me ha empezado a tocar a hacer aplicaciones web, hemos empezado a usar jQuery. En los proyectos había hecho algo, pero siempre por encima y sin saber muy bien qué estaba haciendo. Lo típico de buscar en la documentación o en google, encontrar el trozo de código que hace lo que tú quieres, copy-paste y arreglarlo hasta que funcione.

Pero ahora me he puesto a jugar con jQuery un poco más en serio y la verdad es que me ha gustado lo que he visto.

Aunque parece raro al principio, sobre todo porque no tengo ni idea de javascript, te acostumbras rápido a usarlo. Es muy sencillo y funciona bien, además de ser bastante potente.

Tenemos por un lado su funcionalidad "básica", que permite fácilmente buscar elementos dentro de la página web, cambiar cosas, etc, etc. Y me ha gustado especialmente la sencillez con que se pueden hacer llamadas tipo AJAX y lo fácil que se puede leer la respuesta si viene en formato JSON. De hecho, jQuery te transforma automáticamente esa respuesta JSON en un objeto javascript con los atributos y valores correspondientes al JSON. No sé yo el XML, cada vez me da más "yuyu", incluso desde java, nunca es fácil de leer y siempre tienes que liar el código con clases Document, y Node, y buscando Childs …. 

Para la parte de Drag and Drop, por supuesto tenemos lo básico para hacer lo que queramos, pero lo más "molón" es sortable(), que te da directamente una lista que se puede ordenar arrastrando los items con el ratón sin más necesidad que una línea de código javascript. Se puede incluso hacer varias listas y permitir que los elementos se puedan pasar de una a otra … y sólo requiere una línea de javascript por cada lista.

Tenemos también en jQuery una serie de "Widgets" opcionales, como diálogos, pestañas, acordeones, fechas, etc, etc que también son sencillos de usar. La "pega" es que para que salga algo decente requieren unos CSS más o menos complejos. Por lo que casi no queda más remedio que bajarse alguno de algún sitio ….. pero me ha llamado mucho la atención themeroller. Estos de jQuery lo tienen todo pensado y entrando en la página de themeroller podemos definir con el navegador nuestro propio CSS, viendo cómo queda sobre la marcha según vamos tocando, y luego bajarnos el tema completo junto con las librerías de jQuery (la básica y la de los Widgets).

En fin, me ha gustado mucho todo lo que he visto hasta ahora. Sé que solo he ido haciendo unas pruebas básicas para ir aprendiendo y que en una aplicación real puede haber más "enrevesamiento" del previsto.

Jun 03

Chrome vs Explorer

 Como he comentado más veces, estamos haciendo un portal web con mapa (Geoserver + Openlayers). En ese mapa debemos pintar las posiciones de los barcos (algo similar a http://www.localizatodo.com/mapa/ ). Geoserver ofrece dos tipos de Web Service para obtener los barcos y poder pintarlos en el mapa. Ojo, Geoserver no sabe los datos de los barcos, simplemente los lee de su base de datos y algún proceso externo tiene que rellenar dicha base de datos.

Uno de ellos, WFS, consiste en que a través del WebService y en formato XML te da los datos de los barcos (posición, velocidad, rumbo, nombre del barco, tipo de barco, etc). Es el navegador con javascript (y en concreto la librería OpenLayers), la encargada de dibujar los barcos sobre el mapa.

Pues bien, con esta aproximación y con sólo unos tres mil barcos para probar (la base de datos contiene algo menos de treinta mil), Chrome funciona perfectamente. Se puede hacer zoom en el mapa, desplazarlo y jugar con él sin notar ningún retraso importante en los refrescos. Pero Internet Explorer es otra cosa. Con tres mil barcos…. se queda colgado el navegador entero. En cuanto haces zoom, intentas mover el mapa o cualquier cosa, deja de refrescarse, deja de contestar y ni siquiera puedes abrir otras pestañas, cerrarlas, o cerrar el navegador. En fin, una diferencia importante de eficiencia de javascript entre internet explorer 8 y Chrome.

La solución al final usar el otro Web Service que ofrece Geoserver, el WMS. En este Web Service es el mismo Geoserver (el servidor), el que hace unas imágenes jpg (o el formato que elijamos) con el mapa y los barcos pintados encima. Esta imagen se sirve al explorador cuya única tarea consiste en pintarla. Aun así, Chrome sigue funcionando perfectamente, mientra que con internet explorer ya se puede trabajar sin problemas, pero se le sigue notando más "pastoso" a la hora de mover el mapa y hacer zoom.

Una pena que al ser el navegador más usado por la gente profana, nuestro requisito sea que funcione bien con internet explorer.