Modèle de conception de fabrique abstraite en Java

Bienvenue dans l’exemple de modèle de conception Abstract Factory en Java. Le modèle de conception Abstract Factory est l’un des modèles de création. Le modèle de conception Abstract Factory est presque similaire au modèle Factory Pattern à l’exception du fait qu’il ressemble davantage à une usine de fabriques.

Abstract Factory

Si vous êtes familier avec le modèle de conception de fabrique en Java, vous remarquerez que nous avons une seule classe Factory. Cette classe d’usine renvoie différentes sous-classes en fonction de l’entrée fournie, et la classe d’usine utilise une déclaration if-else ou switch pour y parvenir. Dans le modèle de conception Abstract Factory, nous nous débarrassons du bloc if-else et avons une classe d’usine pour chaque sous-classe. Ensuite, une classe Abstract Factory qui renverra la sous-classe en fonction de la classe d’usine d’entrée. Au début, cela semble confus, mais une fois que vous voyez l’implémentation, c’est vraiment facile à comprendre et à saisir la différence mineure entre les modèles Factory et Abstract Factory. Comme pour notre article sur le modèle de fabrique, nous utiliserons le même superclasse et les mêmes sous-classes.

Modèle de conception d’usine abstraite : Superclasse et sous-classes

Computer.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();
    }
}

PC.java

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;
    }
 
}

Server.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;
    }
 
}

Classe d’usine pour chaque sous-classe

Tout d’abord, nous devons créer une interface d’usine abstraite ou classe abstraite. ComputerAbstractFactory.java

package com.journaldev.design.abstractfactory;

import com.journaldev.design.model.Computer;

public interface ComputerAbstractFactory {

	public Computer createComputer();

}

Remarquez que la méthode createComputer() renvoie une instance de la superclasse Computer. Ensuite, nos classes d’usine implémenteront cette interface et renverront leur sous-classe respective. PCFactory.java

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 même, nous aurons une classe d’usine pour la sous-classe 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);
	}

}

Maintenant, nous allons créer une classe consommatrice qui fournira le point d’entrée pour les classes clientes afin de créer des sous-classes. 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();
	}
}

Remarquez qu’il s’agit d’une classe simple et que la méthode getComputer accepte l’argument ComputerAbstractFactory et renvoie un objet Computer. À ce stade, l’implémentation doit commencer à être claire. Écrivons maintenant une méthode de test simple et voyons comment utiliser l’usine abstraite pour obtenir l’instance des sous-classes. 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 sortie du programme ci-dessus sera :

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

Voici le diagramme de classe de l’implémentation du modèle de conception de l’usine abstraite.

Avantages du modèle de conception de l’usine abstraite

  • Le modèle de conception de l’usine abstraite propose une approche basée sur l’interface plutôt que sur l’implémentation.
  • Le modèle de conception de l’usine abstraite est une « usine de fabriques » et peut être facilement étendu pour accueillir davantage de produits. Par exemple, nous pouvons ajouter une autre sous-classe « Laptop » et une fabrique « LaptopFactory ».
  • Le modèle de conception de l’usine abstraite est robuste et évite la logique conditionnelle du modèle de conception de l’usine.

Exemples du modèle de conception de fabrique abstraite dans JDK

  • javax.xml.parsers.DocumentBuilderFactory#newInstance()
  • javax.xml.transform.TransformerFactory#newInstance()
  • javax.xml.xpath.XPathFactory#newInstance()

Tutoriel vidéo sur le modèle de conception de fabrique abstraite

I recently uploaded a video on YouTube for abstract factory design pattern. In the video, I discuss when and how to implement an abstract factory pattern. I have also discussed what is the difference between the factory pattern and abstract factory design pattern. https://youtu.be/BPkYkyVWOaw

Vous pouvez télécharger le code des exemples depuis mon Projet GitHub.

Source:
https://www.digitalocean.com/community/tutorials/abstract-factory-design-pattern-in-java