Los patrones son formas de describir las mejores prácticas y diseños correctos. Muestran una solución flexible a problemas de programación frecuentes.
El patrón Fábrica permite instanciar objetos en tiempo de ejecución. Se le llama Patrón Fábrica porque es responsable de la "fabricación" de un objeto. Una Fábrica Parametrizada recibe como argumento el nombre de la clase a instanciar.
Example #1 Método de Fábrica Parametrizada
<?php
class Ejemplo
{
// El método de fábrica parametrizada
public static function fabrica($tipo)
{
if (include_once 'Drivers/' . $tipo . '.php') {
$nombreclase = 'Driver_' . $tipo;
return new $nombreclase;
} else {
throw new Exception('Driver no encontrado');
}
}
}
?>
Al definir este método en una clase, permitimos que se puedan cargar al vuelo los drivers. Si la case Ejemplo fuera una clase de abstracción de bases de datos, se podría cargar un driver de MySQL y de SQLite de la siguiente forma:
<?php
// Carga un driver MySQL
$mysql = Ejemplo::fabrica('MySQL');
// Carga un driver SQLite
$sqlite = Ejemplo::fabrica('SQLite');
?>
El patrón Singleton se aplica en situaciones en las que se necesita que sólo haya una instancia de una clase. El ejemplo más común es una conexión a una base de datos. Al implementar este patrón, un programador puede hacer esta única instancia accesible a muchos otros objetos.
Example #2 Función Singleton
<?php
class Ejemplo
{
// Almacena una instancia de la clase
private static $instancia;
// Un constructor privado; previene la creación directa de objetos
private function __construct()
{
echo 'Estoy construido';
}
// El método singleton
public static function singleton()
{
if (!isset(self::$instancia)) {
$c = __CLASS__;
self::$instancia = new $c;
}
return self::$instancia;
}
// Método de ejemplo
public function bark()
{
echo 'Woof!';
}
// Impide que los usuarios clonen la instancia
public function __clone()
{
trigger_error('No se permite la clonación.', E_USER_ERROR);
}
}
?>
Esto permite obtener una única instancia de la clase Ejemplo.
<?php
// Esto fallará dado que el constructor es privado
$test = new Ejemplo;
// Esto siempre devolverá una única instancia de la clase
$test = Ejemplo::singleton();
$test->bark();
// Esto emitirá un E_USER_ERROR.
$test_clone = clone $test;
?>