Patrón de diseño de fábrica abstracto en Java
Bienvenido a Abstract Factory Design Pattern en el ejemplo de Java. El patrón de diseño Abstract Factory es uno de los patrones de creación. El patrón Abstract Factory es casi similar al patrón Factory, excepto por el hecho de que se parece más a una fábrica de fábricas.
Fábrica abstracta
Superclases y subclases de patrón de diseño de fábrica abstracto
Computadora.java
package com.journaldev.design.model;
public abstract class Computer {
public abstract String getRAM();
public abstract String getHDD();
public abstract String getCPU();
@Override
public String toString(){
return "RAM= "+this.getRAM()+", HDD="+this.getHDD()+", CPU="+this.getCPU();
}
}
package com.journaldev.design.model;
public class PC extends Computer {
private String ram;
private String hdd;
private String cpu;
public PC(String ram, String hdd, String cpu){
this.ram=ram;
this.hdd=hdd;
this.cpu=cpu;
}
@Override
public String getRAM() {
return this.ram;
}
@Override
public String getHDD() {
return this.hdd;
}
@Override
public String getCPU() {
return this.cpu;
}
}
Servidor.java
package com.journaldev.design.model;
public class Server extends Computer {
private String ram;
private String hdd;
private String cpu;
public Server(String ram, String hdd, String cpu){
this.ram=ram;
this.hdd=hdd;
this.cpu=cpu;
}
@Override
public String getRAM() {
return this.ram;
}
@Override
public String getHDD() {
return this.hdd;
}
@Override
public String getCPU() {
return this.cpu;
}
}
Clase de fábrica para cada subclase
En primer lugar, debemos crear una interfaz de fábrica abstracta o una clase abstracta. ComputerAbstractFactory.java
package com.journaldev.design.abstractfactory;
import com.journaldev.design.model.Computer;
public interface ComputerAbstractFactory {
public Computer createComputer();
}
Observe que el método createComputer()
devuelve una instancia de la superclase Computer
. Ahora nuestras clases de fábrica implementarán esta interfaz y devolverán su respectiva subclase.
package com.journaldev.design.abstractfactory;
import com.journaldev.design.model.Computer;
import com.journaldev.design.model.PC;
public class PCFactory implements ComputerAbstractFactory {
private String ram;
private String hdd;
private String cpu;
public PCFactory(String ram, String hdd, String cpu){
this.ram=ram;
this.hdd=hdd;
this.cpu=cpu;
}
@Override
public Computer createComputer() {
return new PC(ram,hdd,cpu);
}
}
De manera similar, tendremos una clase de fábrica para la subclase Server
. ServerFactory.java
package com.journaldev.design.abstractfactory;
import com.journaldev.design.model.Computer;
import com.journaldev.design.model.Server;
public class ServerFactory implements ComputerAbstractFactory {
private String ram;
private String hdd;
private String cpu;
public ServerFactory(String ram, String hdd, String cpu){
this.ram=ram;
this.hdd=hdd;
this.cpu=cpu;
}
@Override
public Computer createComputer() {
return new Server(ram,hdd,cpu);
}
}
Ahora crearemos una clase de consumidor que proporcionará el punto de entrada para que las clases de cliente creen subclases. ComputerFactory.java
package com.journaldev.design.abstractfactory;
import com.journaldev.design.model.Computer;
public class ComputerFactory {
public static Computer getComputer(ComputerAbstractFactory factory){
return factory.createComputer();
}
}
Tenga en cuenta que es una clase simple y el método getComputer
acepta el argumento ComputerAbstractFactory
y devuelve el objeto Computer
. En este punto, la implementación debe ser clara. Escribamos un método de prueba simple y veamos cómo usar la fábrica abstracta para obtener la instancia de las subclases. TestDesignPatterns.java
package com.journaldev.design.test;
import com.journaldev.design.abstractfactory.PCFactory;
import com.journaldev.design.abstractfactory.ServerFactory;
import com.journaldev.design.factory.ComputerFactory;
import com.journaldev.design.model.Computer;
public class TestDesignPatterns {
public static void main(String[] args) {
testAbstractFactory();
}
private static void testAbstractFactory() {
Computer pc = com.journaldev.design.abstractfactory.ComputerFactory.getComputer(new PCFactory("2 GB","500 GB","2.4 GHz"));
Computer server = com.journaldev.design.abstractfactory.ComputerFactory.getComputer(new ServerFactory("16 GB","1 TB","2.9 GHz"));
System.out.println("AbstractFactory PC Config::"+pc);
System.out.println("AbstractFactory Server Config::"+server);
}
}
La salida del programa anterior será:
AbstractFactory PC Config::RAM= 2 GB, HDD=500 GB, CPU=2.4 GHz
AbstractFactory Server Config::RAM= 16 GB, HDD=1 TB, CPU=2.9 GHz
Beneficios del patrón de diseño de fábrica abstracta
- El patrón de diseño de Abstract Factory proporciona un enfoque del código para la interfaz en lugar de la implementación.
- El patrón Abstract Factory es \fábrica de fábricas” y se puede ampliar fácilmente para admitir más productos, por ejemplo, podemos agregar otra subclase Laptop y una LaptopFactory de fábrica.
- El patrón Abstract Factory es sólido y evita la lógica condicional del patrón Factory.
Ejemplos de patrones de diseño de fábrica abstracta en JDK
- javax.xml.parsers.DocumentBuilderFactory#newInstance()
- javax.xml.transform.TransformerFactory#nuevaInstancia()
- javax.xml.xpath.XPathFactory#nuevaInstancia()
Video Tutorial de Patrón de Diseño de Fábrica Abstracta
Recientemente subí un video en YouTube para un patrón de diseño de fábrica abstracto. En el video, analizo cuándo y cómo implementar un patrón de fábrica abstracto. También he discutido cuál es la diferencia entre el patrón de fábrica y el patrón de diseño de fábrica abstracto. https://youtu.be/BPkYkyVWOaw
Puede descargar el código de ejemplos de mi Proyecto GitHub.