Entradas con la etiqueta ‘Patrones de diseño’

Programación Orientada a Objetos en JavaScript

Publicado por Iván Gajate el 25 de octubre de 2012 en Desarrollo Web, JavaScript | 3 comentarios »

Para poder hacer una programación orientada a objetos en JavaScript primero tenemos que entender que TODO lo que declaremos se guarda en el espacio global, es como si en Flash lo guardásemos todo el en root (!!).
Por eso para evitar problemas vamos a meter nuestro código dentro de una función, como si fuese una clase de ActionScript (al ser una función no se ejecutará hasta que la llamemos por primera vez).
Además, podemos guardar esta «clase» en una variable y de esta manera instanciarla tantas veces como queramos:

var Cuadrado = function(){
	alert("Soy un cuadrado!!");
};
 
var unCuadrado = new Cuadrado();
var otroCuadrado = new Cuadrado();
var untercerCuadrado = new Cuadrado();

 

Todas las variables que declaremos dentro de esa función no entrará en conflicto con ninguna variable de fuera, y a su vez, desde fuera se podrá preguntar por las variables de dentro:

var unNumero = 0;
 
var Cuadrado = function(){
	this.unNumero = 5;
	var otraVariable = "Foo";
};
 
var unCuadrado = new Cuadrado();
 
alert(unNumero); // 0
alert(unCuadrado.unNumero); // 5
alert(unCuadrado.otraVariable); // undefined

En este ejemplo «declaramos» la variable unNumero en «this«, que hace referencia al propio objeto creado. De hecho, ese this es lo que devuelve la función cuando hacemos un new Cuadrado() y lo que se almacena en la variable unCuadrado.
Todo lo que no esté declarado en this se ejecuta dentro de la función pero no es accesible desde fuera como en el caso de otraVariable.

Sin embargo, podemos devolver cualquier cosa, por ejemplo un objeto creado por nosotros:

var Cuadrado = function(){
	var _api = {};
	_api.unNumero = 5;
 
	var otraVariable = "Foo";
 
	return _api;
};
 
var unCuadrado = new Cuadrado();
 
alert(unCuadrado.unNumero); // 5
alert(unCuadrado.otraVariable); // undefined

Hemos creado un objeto vacío llamado _api que devuelve la función, y con él todas las variables (y métodos) que hayamos declarado dentro. El resto de variables siguen teniendo como ámbito nuestro nuevo objeto pero no son accesibles desde fuera de este.
¡Ya tenemos métodos públicos y privados! 🙂
En efecto, con este sistema es fácil encapsular nuestros métodos privados para hacer mas robusta nuestra clase, y solo dejar visible ciertos métodos públicos que queramos (de ahí el nombre de la variable 🙂

Solo nos queda un detalle: debido a la «peculiar» manera en que se generan los objetos en JavaScript (magia dice Isra 😉 es mas que aconsejable utilizar un método init declarado al principio de nuestra clase y llamado justo antes del final. De esta manera nos aseguramos que cuando accedemos al objeto éste está perfectamente montado y podemos acceder a sus variables y métodos sin problemas.
Quedaría tal que así:

var Cuadrado = function(){
	var _api = {};
	_api.unNumero;
 
	function init(){
		_api.unNumero = 5;
	}
 
	// Este metodo es publico
	_api.metodoPublico = function(){
		alert("Soy un Cuadrado!");
	}
 
	// Metodo privado, solo accesible desde dentro del objeto
	function metodoPrivado(){
		//
	}
 
	init();
	return _api;
};
 
var unCuadrado = new Cuadrado();
 
alert(unCuadrado.unNumero); // 5
unCuadrado.metodoPublico(); // Soy un Cuadrado!

Esto (menos las tres ultimas lineas) lo guadamos en un archivo independiente llamado Cuadrado.js, lo importamos en nuestro html con la etiqueta script

<script type="text/javascript" src="js/Cuadrado.js"></script>

y ya tenemos nuestra estructura de clases lista para darle caña! 🙂

PD: Mi agradecimiento a Isra y Javi que han tenido la paciencia de enseñarme esta forma de trabajar que tanto me reconforta… 😉

AS3 – Singleton

Publicado por Iván Gajate el 6 de junio de 2011 en AS3, Flash, Patrones de diseño | 13 comentarios »

Uno de los patrones de diseño que mas útiles en mi opinión es el Singleton. Si queremos almacenar datos relevantes para nuestro proyecto y que sean accesibles fácilmente desde cualquier sitio es la mejor opción. O para la típica cartela de avisos que solo puede estar abierta una vez y que tiene que llamarse desde muchos sitios.

Para construirlo a mi esta es la forma que mas me gusta:

package {

	public class Modelo {

		private static var _instance:Modelo;

		public function Modelo(singletonenforcer:SingletonEnforcer) {
			if (singletonenforcer == null) {
				throw new Error("Modelo es un Singleton. Para acceder a una instancia hacedlo mediante Modelo.getInstance()");
				return;
			}
		}

		public static function getInstance():Modelo {
			if (!_instance) {
				_instance = new Modelo(new SingletonEnforcer());
			}
			return _instance;
		}

	}
}

class SingletonEnforcer{}

De esta manera podemos acceder así:

Modelo.getInstance().guardarDatos();
Modelo.getInstance().recogerDatos();

Patrón Value Object

Publicado por Iván Gajate el 17 de mayo de 2009 en AS3, Flash, Patrones de diseño, Tutoriales | 18 comentarios »

Este mini patrón de diseño, consiste simplemente en agrupar varios valores dentro de un objeto para enviarlo y recibirlo con mayor comodidad/seguridad.

Yo casi más que un patrón lo considero una buena costumbre de programación, y es que cuando tengo que pasarle a una función mas de 4 ó 5 parámetros, los meto todos en un objeto y hago que esta función sólo espere ese objeto como único parámetro.

// Sin Value Object
public function guardarDatos(nombre:String, apellidos:String, edad:uint, hombre:Boolean):void{
	//
}

// Con Value Object
public function guardarDatos(datos:Object):void{
	//
}

Esto, aparte de hacer el código más legible, hace nuestro programa escalable, pues si en un futuro queremos añadir un nuevo parámetro a la función, no tengo que cambiar su firma (public function guardarDatos(datos:Object):void), sino que le añado una nueva propiedad al objeto y listo, mi función sigue esperando un sólo parámetro.

Leer el resto de esta entrada