sábado, 20 de diciembre de 2014

Patrones de diseño en JavaScript

A la hora de programar es muy recomendable el uso de patrones para agilizar el desarrollo y la lectura del código. Hay diversidad de patrones, cada uno adaptado a las necesidades del entorno, pero todos tienen una misión en común, simplificar el trabajo.

Para aplicar el patrón de diseño del que hablaré a continuación se ha creado una clase de ejemplo cuya finalidad es meramente didáctica, pues carece de funcionalidades de interés (se trata de una simple calculadora).

El script, que se encuentra al final de este artículo, comienza con la directiva use strict que limitará algunas funcionalidades ambiguas de JavaScript y restringirá nombres de variables entre otras cosas. Todo ello con el fin de garantizar la compatibilidad con futuras versiones de JavaScript.

Nos apoyaremos en el uso de patrones durante el nombramiento de nuestras variables y métodos. Es por eso que a la clase Calculator, que vamos a utilizar como ejemplo, no se le llamará de esa manera internamente, tan solo definiremos el nombre de la clase en una variable (publicName) y cada vez que queramos hacer referencia al nombre de la clase utilizaremos esta variable. Esto nos permite entre otras cosas no depender de un nombre y si por cualquier motivo necesitamos cambiar el nombre de la clase no tendremos ningún problema más que cambiar una línea de código.

También debemos intentar utilizar siempre los mismos nombres de variables. Si en un ámbito cerrado tenemos una única matriz que actúa de contenedor de números, lo fácil sería llamarla numbers, cuando quizá lo idóneo sería utilizar un nombre genérico: items, por ejemplo.

A continuación se irán explicando las distintas partes que dan forma a esta clase.

Constructor

Encargado de inicializar la instancia, sobretodo de definir las opciones introducidas y otras variables, además de alguna otra peculiaridad como prescindir del operador new para su creación.

Opciones por defecto

Es muy buena práctica definir todas las opciones disponibles para que estén documentadas. Además, podremos establecer opciones por defecto en diversos entornos según nos convenga y sin modificar la clase, punto muy importante.

Prototipo

En este apartado definiremos las propiedades de nuestra clase, ya sean variables o funciones. También definiremos dentro del prototipo el constructor por si quisiéramos llamarlo de nuevo.

Especial atención a la hora de declarar variables con referencias como objetos o matrices, ya que serán compartidas por todas las instancias, cosa que evitaremos inicializando estas variables desde el constructor, como sucede con la propiedad options. De esta manera, cada vez que creemos una instancia nos aseguraremos que los objetos/matrices del prototipo sean únicos evitando que sean compartidos.

Métodos privados

JavaScript se encuentra limitado en este sentido y para hacer uso de ciertas funcionalidades 100% OOP necesitaremos jugar un poco con el lenguaje para emular un entorno totalmente orientado a objetos. Por lo general se suele utilizar el carácter barra baja (underscore) para indicar que la propiedad es privada.

Funciones globales

Estas funciones se ejecutan fuera del ámbito de la instancia, suelen ser de apoyo y pueden ser llamadas directamente sin declarar una instancia.

Acceso público

Hasta ahora todo el código ejecutado se encontraba envuelto en una función anónima para evitar sobreescribir variables en ámbitos superiores, así que llegados a este punto toca crear un acceso desde fuera. Podemos adaptar el acceso público a distintos entornos. En este caso la adaptación se ha realizado para el entorno del navegador y NodeJS.

Bajo el navegador la variable con mayor ámbito global sería window, y en caso de NodeJS lo ideal sería que nuestro código se comporte como un modulo del mismo. Esto lo conseguiremos definiendo nuestra clase en module.exports, de esta manera el código podrá ejecutarse tanto bajo un navegador (new Calculator()) y en NodeJS (new require('./Calculator.js')).

Para finalizar, dejo el script que contiene la clase para analizar todos los detalles comentados anteriormente.


No hay comentarios:

Publicar un comentario