Este patrón de diseño del software es muy interesante, porque da mucho juego, además de que si lo combinamos con otros puede mejorar mucho nuestros programas. Es decir, simplemente se trata de una clase, que como su nombre indica, Factory, Factory Method o Abstract Factory, se encargan de fabricar objetos para usarlos.
Estos objetos pueden ser cacheados para no volver a crearlos con su coste de crearlos, también puede encargarse de crear otros objetos con todo tipo de patrones de diseño.
Diferencias entre Factory, Factory Method o Fábrica Abstracta
Una Factory normal se encarga simplemente crear objetos de varios tipos.
El Factory Method, consiste en tener un método que implemente la creación de un objeto, y que lo devuelva en el retorno de la función para usarlo externamente.
La Abstract Factory finalmente, es un tipo de fábrica nueva que se define como abstracta, para luego hacer cada implementación según el tipo de objetos que vaya a devolver, a diferencia de la normal.
Esto es más fácil verlo con los fuentes siguientes en PHP, lo mismo sería para cualquier otro lenguaje cambiando su sintaxis.
Al grano, cómo implementar una fábrica normal con sus métodos de fábrica, en PHP
Si vamos al grano con algo de código fuente, se puede ver fácilmente en qué consiste. Por ejemplo, si queremos una fábrica de vehículos que nos devuelva coches, motos o camiones podríamos hacer tal que así:
Detallando un poco más el funcionamiento podríamos tener:
Esto se puede traducir en PHP por ejemplo en lo siguiente:
<?php
class Factory
{
public function getNewCar()
{
return new Car();
}
public function getNewMotorbike()
{
return new Motorbike();
}
public function getNewTruck()
{
return new Truck();
}
}
Si ahora establecemos una interfaz, para seguir con buenas prácticas aplicando la inversión de dependencias, tendremos que podemos modificar la fábrica para hacer algo así:
<?php
class Factory
{
public function getNewCar(): IVehicle
{
return new Car();
}
public function getNewMotorbike(): IVehicle
{
return new Motorbike();
}
public function getNewTruck(): IVehicle
{
return new Truck();
}
}
..podemos seguir definiendo la interfaz:
<?php
interface IVehicle {
}
..y los tres tipos de vehículos:
<?php
class Car implements IVehicle
{
}
<?php
class Motorbike implements IVehicle
{
}
<?php
class Truck implements IVehicle
{
}
Convirtiendo esta fábrica en fábrica abstracta, en PHP
Ahora lo que hacemos es que convertimos la fábrica anterior que tiene un método para cada tipo, en una nueva fábrica abstracta que tiene un método en común. Luego se implementará una clase para cada fábrica en concreto.
Esto es lo que se llama aplicar la inversión de dependencias, metiendo por en medio en este caso, una clase abstracta, para hacer luego la programación de cada fábrica en concreto.
Es decir, la fábrica abstracta podría ser:
<?php
abstract class AbstractVehiclesFactory {
abstract function createVehicle() : IVehicle;
}
..luego las implementaciones de cada fábrica según tipo de vehículo:
<?php
class CarsFactory extends AbstractVehiclesFactory
{
public function createVehicle(): IVehicle
{
return new Car();
}
}
<?php
class MotorbikesFactory extends AbstractVehiclesFactory
{
public function createVehicle(): IVehicle
{
return new Motorbike();
}
}
<?php
class TrucksFactory extends AbstractVehiclesFactory
{
public function createVehicle(): IVehicle
{
return new Truck();
}
}
El resto de código con IVehicle, Car, Motorbike y Truck, quedarían igual..