Este patrón es parte de los patrones de diseño creacionales.

Estos patrones se tratan de instancias clases. Los patrones de diseño creacionales pueden ser divididos en 2 tipos, por creación de clase (que utiliza la magia de la herencia) y por creación de objetos (que delega las responsabilidades como un profesional).

Fábrica Abstracta (Abstract Factory)

  • Brinda una interface para la creación de familias relacionadas u objetos dependientes sin especificar una clase concreta.
  • Una jerarquia que encapsula: las posibles plataformas, y la construcción de un conjunto de productos.
  • El operador new es nocivo para este tipo de patrón.

Problemática

Cuando una aplicación necesita portabilidad, es necesario encapsular las dependencias por plataforma. Estas plataformas pueden incluir, Sistema de ventanas, el sistema operativo, el tipo de dispositivo, las bases de datos, etc.

Por lo general si esta encapsulación no es pensada a futuro, llegarán a existir muchos condicionales (if, elseif) que le dan soporte a los distintos tipos de plataformas, que se van multiplicando a lo largo del proyecto cada vez que se necesita una nueva plataforma.

Estructura

El patrón de Fábrica Abstracta define un metodo (factory) por producto. Cada método encapsula el operador “new" y las clases de los productos por plataforma. Cada plataforma debe ser modelada con una clase derivada de la Factory.



Ejemplo

El propósito de la Fábrica Abstracta es proveer una interface para la creación de familias de objetos relacionados, sin especificar clases concretas.

Este patron se encuentra en una fabrica de moldeado de autopartes. El equipo de corte y moldeo es la Fábrica Abstracta la cual crea las autopartes. La misma maquinaria es utilizada para cortar las puertas, los cofres, las cajuelas, etc. Para diferentes modelos de coches. A través del uso de rodillos que cambian el tipo de acabado, las clases concretas son producidas por la maquinaria que puede ser cambiada en menos de 3 minutos.


Lista de checado

  • Decidir si la independencia de la plataforma y los servicios de creación son el principal problema.
  • Crear una matriz de plataformas contra productos.
  • Definir una interface factory que consista de un método factory por producto.
  • Definir una clase factory derivada por cada plataforma que encapsule todas las referencias al operador new.
  • El cliente debería quitar todas las referencias a new, y utilizar los métodos factory para crear los productos.

Reglas

Algunas veces los patrones creacionales con competencia, y en toros casos con complementarios. Una Fábrica Abstracta puede tener un conjunto de Prototipos de los cuales clonar y retornar objetos de productos.

Los constructores pueden utilizar otros patrones para implementar los componentes a construir. Fabrica Abstracta, Constructor y Prototipo pueden utilizarse como Singleton en sus implementaciones.

Los tres definen un objeto factory que es el responsable de crear las clases para los objetos de producto.
  • Fábrica Abstracta; se encarga de la creación de objetos produciéndolos desde distintas clases.
  • Builder (Construsctor): es un objeto Factory que construye un producto complejo utilizando un protocolo definido.
  • Prototipo: es un objeto factory que construye el producto copiando un objeto prototipo.

El builder se enfoca en construir un objeto complejo paso a paso. La Fábrica Abstracta se enfatiza en una familia de productos. Al final el Builder retorna ese producto.

A menudo los diseños empiezan utilizados un Método Factory (poca complejidad, personalizable, lleno de subclases) y evoluciona en torno a Prototype, o Builder (a veces mas flexible, a veces más complejo) según como el diseñador infiera donde esa flexibilidad es necesaria.


Fábrica Abstracta en Typescript


Supongamos que tengo una fábrica de productos de videojuegos, donde grabo los discos e imprimo portadas. Para ello tengo una serie de clases definidas para los productos:


Esos productos son producidos para 2 plataformas, PlayStation y Xbox para lo cual defino mis clases fabrica:


Por último lo que tengo que hacer es echar a andar mi fábrica, tan fácil como solo correr mis distintos tipos:


Por cierto si quieres correrlo no uno que se haría es un new GameMaker();

Y eso es todo, ¿que pasaría si necesito otro juego, como el Dragon Ball FighterZ?, simplemente tendríamos que agregar ese nuevo producto a nuestra clase producto.

¿Y si ahora queremos Nintendo Switch?, 🤯 bueno pues hay que agregarlo a nuestras fabricas. Y así se logra la combinación de fábrica abstracta con sus productos, por supuesto al inicio parece no tener mucha utilidad.

Sin embargo imaginen hacer una fábrica en base a módulos nuevos o simples archivos .json. Agregar y quitar fábricas en desuso sería tan fácil como agregar y eliminar archivos.

Y ya está, felices arquitecturas 😬