Patrones de diseño: el patrón de fábrica simple
Spanish (Español) translation by Andrea Jiménez (you can also view the original English article)
Cuando piensas en una fábrica, ¿qué se te viene a la mente? Para mí, es un lugar donde se crean las cosas, es decir, es un lugar centralizado donde se producen las cosas. Más tarde, la entrega de dichos productos son realizadas por la fábrica en base a un pedido.
Digamos que estás solicitando un automóvil. Una fábrica creará uno basado en las especificaciones del pedido y luego lo entregará cuando esté completo.
Al igual que sus socios del mundo real, una fábrica de software (es decir, software que implementa el patrón de diseño de fábrica) es un objeto que es responsable de crear y entregar otros objetos basados en los parámetros recibidos.
Hay tres variaciones del patrón de fábrica:
- Patrón de fábrica simple. Esto permite interfaces para crear objetos sin exponer la lógica de creación de objetos al cliente.
- Patrón de método de fábrica. Esto permite interfaces para crear objetos, pero permite que las subclases determinen qué clase instanciar.
- Patrón de fábrica abstracto. A diferencia de los dos patrones anteriores, una fábrica abstracta es una interfaz para crear objetos relacionados sin especificar ni exponer sus clases. También podemos decir que proporciona un objeto de otra fábrica que es responsable de crear los objetos necesarios.
El problema
Supongamos que tienes una clase de automóvil que contiene todas las propiedades y métodos relevantes para un automóvil. En su forma más básica, lo crearías así:
1 |
$car = new Car(); |
Inmediatamente, a medida que pasa el tiempo, debe haber algún cambio en la forma en que se crea el objeto Car. Necesitamos crear objetos de clase que se basen en el Tipo carrito en lugar de solo en Car. Así que debes hacer cambios en todos los lugares donde creaste el objeto de esta clase Car.
Pero, con el paso del tiempo, inevitablemente tendrá que haber cambios en la forma en que se crea el objeto Car. Por ejemplo, necesitamos crear clases basadas en un tipo Car en lugar de solo Car. Como tal.
En lugar de hacer eso, sería una mejor decisión crear una clase que implemente el patrón Factory.
La solución
En la sección anterior reconocimos que estábamos creando un objeto de tipo Car usando la palabra clave new. Y posteriormente, se decide crear un objeto de la clase Car, pero basado en el tipo Car como Sedán, SUV, entre otros.
O deberíamos colocar el código de creación de la clase de tipo Car en todos los lugares cuando sea necesario o implementar Factory para manejarlo de manera eficaz. Consulta el bloque de código que muestra la implementación del Patrón de fábrica simple.
1 |
<?php
|
2 |
|
3 |
class carFactory { |
4 |
|
5 |
public function __construct() { |
6 |
// ... //
|
7 |
}
|
8 |
|
9 |
public static function build ($type = '') { |
10 |
|
11 |
if($type == '') { |
12 |
throw new Exception('Invalid Car Type.'); |
13 |
} else { |
14 |
|
15 |
$className = 'car_'.ucfirst($type); |
16 |
|
17 |
// Assuming Class files are already loaded using autoload concept
|
18 |
if(class_exists($className)) { |
19 |
return new $className(); |
20 |
} else { |
21 |
throw new Exception('Car type not found.'); |
22 |
}
|
23 |
}
|
24 |
}
|
25 |
}
|
En la clase anterior, puedes ver que tenemos un método estático disponible que es responsable de crear el objeto según el tipo que pases. Ahora necesitamos clases concretas de diferentes tipos de automóviles, como los que enumeramos a continuación:
1 |
<?php
|
2 |
|
3 |
class car_Sedan { |
4 |
|
5 |
public function __construct() { |
6 |
echo "Creating Sedan"; |
7 |
}
|
8 |
|
9 |
}
|
10 |
|
11 |
class car_Suv { |
12 |
|
13 |
public function __construct() { |
14 |
echo "Creating SUV"; |
15 |
}
|
16 |
|
17 |
}
|
En este punto, tenemos nuestras clases de fábrica y concreto listas para usar, así que practiquémoslo para crear objetos tipo automóvil requeridos.
1 |
// Creating new Sedan
|
2 |
$sedan = carFactory::build('sedan'); |
3 |
|
4 |
// Creating new SUV
|
5 |
$suv = carFactory::build('suv'); |
Adición de nueva clase
La adición de una nueva clase es simple: crea una clase concreta y ya estás listo para comenzar. Por ejemplo:
1 |
<?php
|
2 |
class car_Luxury { |
3 |
|
4 |
public function __construct() { |
5 |
echo "Creating Luxury"; |
6 |
}
|
7 |
|
8 |
}
|
9 |
|
10 |
// Creating new Luxury
|
11 |
$luxury = carFactory::build('luxury'); |
Conclusión
Cuando se trata del patrón de fábrica, analiza el uso de la palabra clave new para crear un nuevo objeto como dañino. La fábrica nos permite tener una ubicación centralizada pues se crean todos nuestros objetos.



