El Abstract Factory define una interfaz para crear una familia de objetos relacionados o que dependen entre sí, sin especificar sus clases concretas.
La necesidad de crear familias de productos que, idealmente, deben ser usados juntos, desacoplando el código de creación del código de los productos.
La solución que propone el Abstract Factory es:

Este patrón es recomendable cuando:
Consistencia de Productos: Asegura que los productos que se crean son compatibles entre sí.
Intercambiabilidad: Facilita el cambio entre diferentes familias de productos.
Aislamiento: Separa los detalles de implementación de los productos del código cliente.
Complejidad: Puede aumentar la complejidad del código debido a la gran cantidad de clases e interfaces involucradas.
Dificultad para agregar nueva familia de productos: La interfaz fábrica abstracta fija los tipos de productos que se pueden crear, por lo que agregar nuevas familias implica cambiar esta interfaz y todas las subclases.
Pensemos en un módulo de software de creación de interfaces gráficas.
Debe estar preparado para funcionar en múltiples sistemas operativos (Windows, MacOS, Linux).
Cada sistema operativo tiene su propia manera de dibujar elementos, como ventanas, botones, cuadros de texto, menúes.
Los clientes deben poder crear cada familia de elementos correspondientes en base al sistema operativo que estén usando, desacoplando la creación del uso de los elementos.
Implementamos un Abstract Factory que permite crear toda la familia de objetos para un determinado sistema operativo.
Por un lado las clases de creación correspondientes al Abstract Factory, los creadores concretos para Windows y para MacOS, y por otro las clases de Productos, correspondientes a botón (Button) y cuadro de texto (TextBox), cada una con sus propias implementaciones para Windows y MacOS.
El creador de Windows (WindowsFactory) creará el botón y el cuadro de texto correspondiente a Windows, y lo mismo hará el MacOSFactory, pero usando los elementos de MacOS.

Codificamos en Java lo que preparamos en el diagrama.
Definimos interfaces para los elementos básicos de la interfaz de usuario que queremos crear. En este caso, botones y cuadros de texto.
interface Button {
void paint();
}
interface TextBox {
void render();
}
Creamos implementaciones específicas de las interfaces de botones y cuadros de texto para cada sistema operativo (Windows y MacOS).
class WindowsButton implements Button {
public void paint() {
System.out.println(“Render a button in a Windows style”);
}
}
class MacOSButton implements Button {
public void paint() {
System.out.println(“Render a button in a MacOS style”);
}
}
class WindowsTextBox implements TextBox {
public void render() {
System.out.println(“Render a text box in a Windows style”);
}
}
class MacOSTextBox implements TextBox {
public void render() {
System.out.println(“Render a text box in a MacOS style”);
}
}
Definimos una interfaz para la fábrica abstracta, que especifica los métodos para crear botones y cuadros de texto.
interface GUIFactory {
Button createButton();
TextBox createTextBox();
}
Implementamos fábricas concretas para cada sistema operativo. Estas fábricas saben cómo crear los elementos de la interfaz específica para su sistema operativo.
class WindowsFactory implements GUIFactory {
public Button createButton() {
return new WindowsButton();
}
public TextBox createTextBox() {
return new WindowsTextBox();
}
}
class MacOSFactory implements GUIFactory {
public Button createButton() {
return new MacOSButton();
}
public TextBox createTextBox() {
return new MacOSTextBox();
}
}
El cliente usa la fábrica abstracta para crear los elementos de la interfaz. No sabe qué implementación concreta está usando, algo que que permite cambiar las fábricas fácilmente sin alterar el resto del código.
class Application {
private Button button;
private TextBox textBox;
public Application(GUIFactory factory) {
button = factory.createButton();
textBox = factory.createTextBox();
}
public void paint() {
button.paint();
textBox.render();
}
}
Los participantes que vimos antes son: FabricaAbstracta, FabricaConcreta, ProductoAbstracto, ProductoConcreto. Cliente:
Este ejemplo demuestra el uso del Abstract Factory para crear familias de objetos relacionados (botones y cuadros de texto).
De esta manera podemos intercambiar fácilmente entre diferentes implementaciones (Windows y MacOS) sin cambiar el código del cliente.
Las clases FabricaAbstracta suelen implementarse con métodos de fabricación (Factory Method).
Las clases FabricaAbstracta también pueden implementarse usando prototipos (Prototype), almacenando un conjunto de prototipos para clonarlos.
Las Fabricas Concretas suele implementarse como Singletons.