viernes, 27 de abril de 2012

El patrón Módulo en JavaScript

El patrón módulo se ha hecho tremendamente popular entre los desarrolladores de JavaScript porque proporciona una buena forma de estructurar y organizar el código que compone un proyecto (múltiples módulos) o una librería (normalmente un único módulo).

El patrón se basa en dos elementos fundamentales:
  • Definir un espacio de nombres
  • Utilizar una función auto-ejecutable para devolver un objeto con la funcionalidad que necesitamos

Definimos el espacio de nombres para que todos nuestros objetos y variables queden siempre dentro de una única variable global ( nuestro namespace ).

Después utilizamos una función autoejecutable para devolver un objeto que contiene todas las propiedades y métodos que necesitamos. Esta función se pueden definir también variables y métodos privados, que no serán accesibles desde fuera y no formarán parte de las propiedades del objeto devuelto.

Un ejemplo básico del patrón módulo sería:

var myModule = (function () {
   var privateVar1 = 1;
   var privateVar2 = "dos";
 
   function privateMethod() {
     // metodo privado
   };
   return {
       publicProperty: " una variable pública ",
       publicMethod: function () {
           //esto es un método público de nuestro módulo,
           //que utilizará internamente el método y 
           //variables privadas definidas
       
        } 
   }
}());

El código anterior muestra el patrón tal y como lo popularizó Douglas Crockford. La función se ejecuta automáticamente y devuelve el objeto en la variable myModule.

Los métodos se podrán acceder desde fuera usando nuestra entrada en el espacio de nombres ( myModule ). De esta forma el módulo dejará visible únicamente una variable global que dará acceso a sus métodos y propiedades.

Cuando definimos un módulo único, el espacio de nombres consiste sólo en declarar una variable que contendrá el objeto devuelto. Cuando tenemos aplicaciones más complejas, compuestas por varios módulos, podemos tener espacios de nombres con varios niveles de profundidad, del tipo:

mailApp.inboxManager
mailApp.notifications
mailApp.cache
....


¿Porqué no asignar el objeto directamente?


Esta es una pregunta muy lógica, si al final va a quedar algo como esto:

var myModule = {
           publicProperty: " una variable pública ",
           publicMethod: function () {
              //esto es un método público de nuestro módulo,
              //que utilizará internamente el método y 
              //variables privadas definidas
       
           } 
}


podríamos crear módulos así desde el principio y definir todas nuestras funciones directamente dentro del objeto que asignamos a myModule, ¿no?.
Sí. Si no queremos/necesitamos tener ninguna variable ni método privado, podríamos hacerlo. De hecho esto es otra forma muy común de definir un módulo.
El patrón Módulo es más potente porque proporciona la posibilidad de definir elementos privados, encapsulados dentro del objeto y no accesibles desde fuera. Sólo se proporciona una API pública concreta, escondiendo todo lo demás.

Modulo revelado. Una versión mejorada del patrón

Christian Heilmann propuso una pequeña variación sobre el patrón módulo tradicional que proporciona algunas ventajas:


var myModule = (function () {
   var variable1 = 1;
   var variable2 = "dos";
   var variable3 = "tres";
 
   function oneMethod() {
     // despues podemos hacer este método público o privado
   }

   function anotherMethod() {
     // despues podemos hacer este método público o privado
   }

   function oneMoreMethod() {
     // despues podemos hacer este método público o privado
   }

   return {
      publicProperty: variable3,
      publicMethod: oneMoreMethod
   }
}());


El patrón Modulo Revelado de Heilmann soluciona los siguientes problemas:

En el patrón original, las propiedades y funciones privadas se declaran de forma diferente de las públicas. Ahora todas las propiedades se declaran igual. Al final, en el return, 'revelamos' sólo los métodos/propiedades que queremos hacer públicas.

Facilita los cambios de visibilidad en el futuro ( pasar una propiedad pública a privada y viceversa).

No tenemos que utilizar nombres largos para acceder desde una función pública a otra. Por ejemplo, si tenemos publicMethod2() que utiliza internamente publicMethod1(), antes tenia que llamarlo con el prefijo del espacio de nombres:


var myModule = (function () {
   ...
   ...
   return {
      publicMethod1: function () { ... },
      publicMethod2: function () {
        ...
        var tmp = myModule.publicMethod1(); 
        ...
      } 
 }
}());

Esto puede ser muy engorroso para proyectos grandes ( el uso de this trata de evitarse en este patrón ). Con el nuevo modelo, desde dentro de una función puede accederse a otra simplemente con su nombre.

¿Y si usamos una función constructora de toda la vida?

Las dos formas de crear módulos que hemos visto a ahora no requieren ser instanciadas utilizando el operador new, pero también podemos simplemente utilizar una función constructora para crear un módulo:


    
var myModule = new function () {
   var privateVar1 = 1;
   var privateVar2 = "dos";
   var privateMethod = function () {
      // metodo privado
   }
 
   this.publicProperty: " una variable pública ";

   this.publicMethod = function () {
       //esto es un método público de nuestro módulo,
       //que utilizará internamente el método y 
       //variables privadas definidas
       
    }; 
 }

Estamos instanciando el constructor directamente con new y guardando el objeto creado en la variable myModule.
Este método nos permite también tener variables y métodos privados y devolver sólo una API pública. El API ofrecido al exterior está formada por todas las propiedades que declaramos como this.property.

Douglas Crockford explica en este artículo que no es una buena idea utilizar new directamente delante de function. No proporcionan ninguna ventaja a la hora de crear objetos.

myObj = new function () {
    this.type = 'core';
};

Es mejor utilizar un objeto literal. Es más corto y más rápido:

myObj = {
    type: 'core'
};

Incluso si necesitamos utilizar variables privadas, es mejor utilizar el patrón módulo. Al utilizar el operador new para invocar a la función, se crea también un prototipo ( otro objeto ) que no nos sirve para nada en este caso. Si no utilizamos new no se creará el prototipo.

La función constructora es más apropiada cuando vamos a necesitar varias instancias del objeto que creamos, con diferentes parámetros de inicialización (para esto utilizamos this) y, sobre todo, si necesitamos la herencia (prototipo). En el caso de un módulo, lo normal es crear un objeto único.


Referencias:

Show love to the module pattern
Revealing module pattern
Module pattern vs anonymous constructor (Stack Overflow)
Design patterns - Module (Addy Osmani)


viernes, 20 de abril de 2012

Telefónica como socio de Mozilla en b2g

Telefónica ha anunciado su colaboración con el proyecto Boot to Gecko de la fundación Mozilla, ¿en que consiste esta alianza? .


Telefónica Digital empezó a trabajar en el proyecto Open Web Device ( OWD ) a principios de 2011 con el objetivo de desarrollar un teléfono móvil donde las aplicaciones web fueran sus aplicaciones nativas y dando acceso a todas las funcionalidades del hardware ( localización, marcador, altavoz, cámara , acelerómetros, etc) a través de JavaScript.

Mozilla, trabajando por su lado, anunció su proyecto Boot to Gecko en en julio de 2011 con el objetivo de desarrollar un sistema operativo para móviles basado totalmente en la web y en estándares abiertos. Las similitudes entre ambos proyectos eran evidentes y las dos compañías comenzaron una colaboración que ha impulsado el desarrollo de la plataforma b2g hasta el punto de poder presentarlo en funcionamiento sobre un dispositivo real en el MWC de febrero de 2012.

Así es cómo Telefónica describe su colaboración en las FAQ de la página  openwebdevice.com :

“Telefónica had the clear vision of the concept and how to move it forward in 2010. Telefonica’s R&D department prototyped the full concept and when Mozilla announced the Boot2Gecko project, both development teams started working together as one team. Currently, Mozilla is providing the web technology, and Telefónica is collaborating in integrating this technology with the underlying kernel, as well as providing the User Experience and services.”

Uno de los objetivos que persigue telefónica con este proyecto es conseguir móviles de grandes prestaciones a bajo coste para servir el enorme mercado latinoamericano que no tiene un gran poder adquisitivo.

Telefónica se ha comprometido también con la idea de los estándares abiertos y con impulsar la adopción de HTML5 en la industria de la telefonía. El objetivo es que no haya ningún API propietario en la arquitectura de los dispositivos.

El nuevo sistema operativo se está desarrollando sobre equipos con un chipset de Qualcomm que de esta forma se une también a los actores del proyecto.

lunes, 16 de abril de 2012

Boot To Gecko. La jugada maestra de Mozilla

A mediados de 2011 Mozilla anunció que preparaba un nuevo sistema operativo para móviles basado en gecko, el motor de presentación de su navegador Firefox. El nombre de este nuevo sistema expresa perfectamente su filosofía y su principal aportación: el móvil arranca directamente a un navegador. Todo lo que veamos y manejemos en él será realmente una aplicación web.

Esta filosofía es una aportación interesante porque significa que desarrollar aplicaciones nativas para este tipo de teléfonos es desarrollar para un navegador. Todos los elementos que veamos en pantalla estarán construidos con HTML, CSS y Javascript. Todos!, incluidos los más elementales, como el teclado numérico para llamar por teléfono, la pantalla de ajustes de configuración o el control del brillo.

¿VaporWare?


No. Mozilla ha conseguido ya algunos socios importantes para el proyecto y ha presentado un prototipo funcional en el Mobile World Congress de Barcelona en Febrero del 2012.

De hecho, en el MVC hemos podido ver dos prototipos con B2G, uno presentado por Mozilla y otro presentado por Telefónica. La diferencia del UI de los dos prototipos ha dejado muy claras las posibilidades de personalización total que ofrece este sistema operativo en el que todo lo que vemos es HTML5


Interface de usuario de Telefónica:



Interface de usuario de Mozilla

Estas imágenes también ha dejado muy claro que los encargados de diseño gráfico de Mozilla están varios años por delante de los de Telefónica.

Los socios declarados


Telefónica ha anunciado que colabora en el proyecto y aportará terminales. Ha anunciado también su intención de sacar a la venta un terminal a finales de 2012.

Qualcomm es la empresa encargada del desarrollo de los chips para el teléfono

Deutsche telekom colabora en el desarrollo del sistema aportando ingenieros.

Desafíos del proyecto


Las dificultades más importantes a las que se enfrenta el proyecto son de tipo técnico. Hay que desarrollar API’s nuevas para dar acceso al navegador a los componentes del teléfono. Debemos ser capaces de manejar, con javascript, la cámara, el usb, el altavoz, el micrófono, hacer llamadas telefónicas, enviar SMS, etc.
Mozilla trabaja en desarrollar estas nuevas interfaces y estandarizarlas.