miércoles, 29 de febrero de 2012

Patrones de diseño II - Singleton

Aquí venimos de nuevo con un nuevo patrón de diseño, el denominado singleton. Este patrón nos servirá para cuando queremos que un objeto tenga una sola y única instancia en toda la aplicación, como por ejemplo al conexión a la base de datos.
La conexión a bases de datos consume muchos recursos del servidor, por lo que nos interesa, conectar una sola vez y realizar todas las consultas necesarias, además de esta forma, nos evitamos tener que crear múltiples objetos que también hacen que la aplicación ocupe más memoria.

A continuación podéis ver la estructura básica de un singleton y después lo explicaremos detalladamente.

/**
 * Objeto del cual deseamos tener una sola instancia
 * en toda la aplicación.
 */
class mi_objeto
{
        /**
         * Aquí se almacenará la única instancia existente
         * del propio objeto.
         *
         * @var mi_objeto
         */
        private static $instancia;

        /**
         * Constructor para la creación de una instancia
         * del objeto.
         */
        private function __construct(){}

        /**
         * Método que siempre devuelve la misma instancia
         * del objeto.
         */
        public static function getInstance()
        {
                if ( !self::$instancia )
                {
                        self::$instancia = new self;
                }

                return self::$instancia;
        }
}


La primera parte y fundamental del código es la variable $instancia.
private static $instancia;
Esta variable almacenará la única instancia disponible en toda la aplicación. Esta variable es estática, ya que debe estar siempre accesible. Si no sabéis que es o para que sirve una variable estática, os recomiendo ver los ejemplos disponibles en la documentación oficial de php.

Más adelante nos encontramos con algo que al principio parece extraño y es que el constructor de la clase es privado. Como hemos dicho solo queremos una instancia en toda la aplicación y es por eso que el constructor es privado, para que nadie pueda realizar por desconocimiento o despiste algo como
$variable = new mi_objeto();
ya que al ser el constructor privado, esto lanzaría un error en la aplicación y evitaría la creación descontrolada de objetos.

Llegados a este punto muchos se preguntarán como se hace entonces para poder crear una un objeto, teniendo el operador new bloqueado. Pues la respuesta es sencilla como ejecutar el método getInstance.
$obj = mi_objeto::getInstance();
Como puede verse en el código del método getInstance, lo que hace es primero que todo comprobar si el objeto ha sido creado anteriormente y en caso de que no haya sido creado anteriormente lo crea y lo devuelve. A partir de este momento, todas las veces que queramos obtener un objeto de la clase mi_objeto, ya no se devolverá una nueva instancia, si no que se obtendrá la generada por primera vez.

A continuación dejo un ejemplo práctico de una clase singleton, con un ejemplo de su funcionamiento. Probad a jugar un poco con ella y pensar posibles usos.
/**
 * Objeto del cual deseamos tener una sola instancia
 * en toda la aplicación.
 */
class mi_objeto
{
        /**
         * Aquí se almacenará la única instancia existente
         * del propio objeto.
         *
         * @var mi_objeto
         */
        private static $instancia;

        /**
         * Variable para almacenar un número
         */
        public $numero;

        /**
         * Constructor para la creación de una instancia
         * del objeto.
         */
        private function __construct(){}

        /**
         * Método que siempre devuelve la misma instancia
         * del objeto.
         */
        public static function getInstance()
        {
                if ( !self::$instancia )
                {
                        self::$instancia = new self;
                }

                return self::$instancia;
        }
}

//Creo un objeto y le asigno un numero
$var = mi_objeto::getInstance();
$var->numero = 23;

//Elimino el contenido de la varible.
$var = null;

//Vuelvo a obtener una instancia del objeto.
//Al ser un singleton lo que se obtendrá es la
//misma instancia que estaba en $var
$nueva_var = mi_objeto::getInstance();

//Imprimirá el número 23
echo $nueva_var->numero;

Os dejo tanto el código base del singleton como del ejemplo para su descarga.

domingo, 26 de febrero de 2012

Patrones de diseño I - MVC


Este es el primer articulo de una serie de artículos que haré sobre patrones de diseño ,que considero todo el mundo debería conocer. Empezaré por el MVC, ya que es uno de los más importantes y es utilizado por todos los frameworks más famosos en la actualidad, como por ejemplo Symfony.

El patrón Modelo, Vista, Controlador o en sus siglas (MVC), es un patrón de arquitectura, por lo que nos ayudará a que nuestra aplicación sea mantenible y respete varios principios como DRY (Don't Repeat Yourself) y KISS (Keep It Simple Stupid). Para los que no conozcan estos principios aconsejo que se queden con sus ideas, ya que son principios muy sencillos e incluso obvios, siendo muy útiles para el día a día.

La característica principal del MVC es que divide nuestra aplicación en tres capas, de forma que cada una de ellas se ocupa de una sola cosa. En la siguiente imagen podemos ver gráficamente como es la estructura del MVC y como se comunican las capas. 
Comunicación entre capas

No os preocupéis si no entendéis el gráfico, ya que se irá explicando cada parte, para que quede claro su funcionamiento. Mientras explicamos las distintas capas, veremos como crear una calculadora básica, con las operaciones de suma y resta, para que se entienda mejor el funcionamiento del patrón. Esta calculadora está pensada para propósitos académicos por lo que no debe utilizarse este código en un entorno de producción.

El modelo

Es la capa encargada de almacenar y procesar datos. No debemos caer en el pensamiento de que esta capa es únicamente para el acceso a la base de datos, ya que tareas tal como hacer una suma o formatear datos deben ir también en esta capa.

En el caso de la calculadora que ponemos en el ejemplo, las operaciones con datos que se realizan son las de suma y las de resta.

/**
 * Clase encargada del tratamiento de los datos.
 */
class Modelo
{
	/**
 	 * Realiza una suma.
	 */
	public function sumar( $a, $b )
	{
		return $a+$b;
	}

	/**
	 * Realiza una resta.
	 */
	public function restar( $a, $b )
	{
		return $a-$b;
	}
}

Como puede verse en el ejemplo en la clase del modelo solo recibimos datos, realizamos operaciones y devolvemos el resultado, por lo que tendremos todas las operaciones centralizadas en esta clase, cumpliendo así con el principio DRY.

La vista

Es la encargada de mostrar los datos al usuario, de manera que será el único punto de salida de información hacia el navegador del usuario. En esta capa se puede usar tanto un gestor de plantillas como Twig o usar directamente PHP + HTML como haremos en nuestro ejemplo.

/**
 * Clase encargada de mostrar al usuario el formulario y el resultado de la operación.
 */
class Vista
{
	/**
 	 * Método que envía al usuario el html/xml/.../json correspondientes
	 */
	public function render( $resultado )
	{
		echo <<<HTML
<!doctype html>
<?xml version="1.0" encoding="UTF-8"?>
<html xmlns="http://www.w3.org/1999/xhtml">
	<head>
		<title>Mi calculadora</title>
	</head>
	<body>
		El resultado de la operación es: $resultado
		<form>
			<p>
				Número: <input type="text" name="a"/>
			</p>
			<p>
				Número: <input type="text" name="b"/>
			</p>
			<p>
				Operación: <input type="radio" name="action" value="sumar" checked="checked"/> Sumar <input type="radio" name="action" value="restar"/> Restar
			</p>
			<p>
				<input type="submit" name="submit" value="Calcular"/>
			</p>
		</form>
	</body>
</html>
HTML;
	}
}

Como podemos ver, tiene un método que permite mostrar un HTML por pantalla que contiene el resultado de la operación. Esta capa es la única que tiene permitido enviar datos directamente al usuario y es de lo único que se encarga.

El controlador

Este es el único punto de entrada a la aplicación y es el que se encarga de pedir los datos necesarios al modelo y enviárselos a la vista, para que el usuario pueda visualizarlos.

/**
 * Único punto de entrada de la aplicación y quien decide que acciones se van a
 * realizar y que se le mostrará al usuario.
 */
class Controlador
{
	/**
	 * Método que arranca nuestra aplicación
	 */
	public function run()
	{
		$resultado = 0;
		switch( $_GET['action'] )
		{
			case 'sumar':
				$modelo = new Modelo();
				$resultado = $modelo->sumar( $_GET['a'], $_GET['b'] );
				break;
			case 'restar':
				$modelo = new Modelo();
				$resultado = $modelo->restar( $_GET['a'], $_GET['b'] );
				break;
		}

		$vista = new Vista();
		$vista->render( $resultado );				
	}
}

En el código vemos como la función run es la que se encarga de recoger los datos del navegador, pedir los cálculos al modelo y finalmente con el resultado del modelo decirle a la vista que envíe la respuesta a nuestro usuario.

El flujo completo de la petición para una suma sería el siguiente:

Finalmente, para ejecutar la aplicación, bastaría con ejecutar las siguientes lineas:
$aplicacion = new Controlador();
$aplicacion->run();


Dejo el código completo del ejemplo para su descarga y que lo podáis probar.

Esta es mi primera entrada en un blog, por lo que espero que os haya gustado, en caso de encontrar erratas o estéis en desacuerdo en algún concepto, agradecería que lo comentarais.