logo

Modèle de conception de méthode d'usine

Le modèle de conception de la méthode Factory est un modèle de conception créative qui fournit une interface pour créer des objets dans une superclasse, permettant aux sous-classes de modifier le type d'objets qui seront créés. Il encapsule la logique de création d'objets dans une méthode distincte, favorisant un couplage lâche entre le créateur et les objets créés. Ce modèle est particulièrement utile lorsque les types exacts d'objets à créer peuvent varier ou doivent être déterminés au moment de l'exécution, permettant ainsi la flexibilité et l'extensibilité de la création d'objets.

Table des matières



Qu'est-ce que le modèle de conception de la méthode d'usine ?

Le modèle de conception de méthode d'usine est un modèle de conception créationnel utilisé en génie logiciel pour fournir une interface permettant de créer des objets dans une superclasse, tout en permettant aux sous-classes de modifier le type d'objets qui seront créés. Il encapsule la logique de création d'objets dans une méthode distincte, faisant abstraction du processus d'instanciation et favorisant un couplage lâche entre le créateur et les objets créés. Ce modèle permet la flexibilité, l'extensibilité et la maintenabilité de la base de code en permettant aux sous-classes de définir leur propre implémentation de la méthode d'usine pour créer des types spécifiques d'objets.

comment initialiser un tableau en Java

Quand utiliser le modèle de conception de méthode d’usine ?

Utiliser le modèle de conception de la méthode d'usine :

  • Lorsque vous souhaitez encapsuler la création d'objets : Si vous disposez d'un processus de création d'objet complexe ou si le processus peut varier en fonction des conditions, l'encapsulation de cette logique dans une méthode d'usine peut simplifier le code client et favoriser la réutilisation.
  • Lorsque vous souhaitez dissocier le code client des classes concrètes : L'utilisation du modèle de méthode Factory vous permet de créer des objets via une interface ou une classe abstraite, en extrayant les détails d'implémentation spécifiques des classes concrètes du code client. Cela favorise un couplage lâche et facilite la modification ou l'extension du système sans affecter le code client existant.
  • Lorsque vous devez prendre en charge plusieurs variantes de produits : Si votre application doit créer différentes variantes d'un produit ou si de nouveaux types de produits peuvent être introduits à l'avenir, le modèle de méthode d'usine offre un moyen flexible de prendre en compte ces variations en définissant des méthodes d'usine pour chaque type de produit.
  • Lorsque vous souhaitez prendre en charge la personnalisation ou la configuration : Les usines peuvent être utilisées pour encapsuler la logique de configuration, permettant aux clients de personnaliser le processus de création en fournissant des paramètres ou des options de configuration à la méthode d'usine.

Composants du modèle de conception de méthode d'usine

1. Créateur

Il s'agit d'une classe abstraite ou d'une interface qui déclare la méthode factory. Le créateur contient généralement une méthode qui sert de fabrique pour créer des objets. Il peut également contenir d'autres méthodes fonctionnant avec les objets créés.

numpy unique

2. Créateur de béton

Les classes Concrete Creator sont des sous-classes de Creator qui implémentent la méthode d'usine pour créer des types spécifiques d'objets. Chaque Concrete Creator est responsable de la création d’un produit particulier.

3. Produit

Il s'agit de l'interface ou de la classe abstraite pour les objets créés par la méthode d'usine. Le produit définit l'interface commune pour tous les objets que la méthode de fabrique peut créer.

4. Produit en béton

Les classes Concrete Product sont les objets réels créés par la méthode d’usine. Chaque classe Concrete Product implémente l’interface Product ou étend la classe abstraite Product.

Exemple de modèle de conception de méthode d'usine

Vous trouverez ci-dessous l'énoncé du problème pour comprendre le modèle de conception de méthode d'usine :

Considérons une application logicielle qui doit gérer la création de différents types de véhicules, tels que les deux-roues, les trois-roues et les quatre-roues. Chaque type de véhicule possède ses propres propriétés et comportements spécifiques.

1. Sans modèle de conception de méthode d'usine

Java
/*package whatever //do not write package name here */ import java.io.*; // Library classes abstract class Vehicle {  public abstract void printVehicle(); } class TwoWheeler extends Vehicle {  public void printVehicle() {  System.out.println('I am two wheeler');  } } class FourWheeler extends Vehicle {  public void printVehicle() {  System.out.println('I am four wheeler');  } } // Client (or user) class class Client {  private Vehicle pVehicle;  public Client(int type) {  if (type == 1) {  pVehicle = new TwoWheeler();  } else if (type == 2) {  pVehicle = new FourWheeler();  } else {  pVehicle = null;  }  }  public void cleanup() {  if (pVehicle != null) {  pVehicle = null;  }  }  public Vehicle getVehicle() {  return pVehicle;  } } // Driver program public class GFG {  public static void main(String[] args) {  Client pClient = new Client(1);  Vehicle pVehicle = pClient.getVehicle();  if (pVehicle != null) {  pVehicle.printVehicle();  }  pClient.cleanup();  } }>
Sortir
I am two wheeler>

Quels sont les problèmes avec la conception ci-dessus ?

Dans la conception de code ci-dessus :

  • Couplage serré: La classe clientClient>instancie directement les classes concrètes (TwoWheeler>etFourWheeler>) en fonction du type d'entrée fourni lors de sa construction. Cela conduit à un couplage étroit entre le client et les classes concrètes, rendant le code difficile à maintenir et à étendre.
  • Violation du principe de responsabilité unique (SRP) : LeClient>La classe est chargée non seulement de déterminer le type de véhicule à instancier en fonction du type d'entrée, mais également de gérer le cycle de vie de l'objet véhicule (par exemple, le nettoyage). Cela viole le principe de responsabilité unique, qui stipule qu'une classe ne devrait avoir qu'une seule raison de changer.
  • Évolutivité limitée : L'ajout d'un nouveau type de véhicule nécessite de modifier leClient>classe, qui viole le principe ouvert-fermé. Cette conception n'est pas évolutive car elle ne peut pas s'adapter à de nouveaux types de véhicules sans modifier le code existant.

Comment éviter le problème ?

  • Définir l'interface d'usine : Créer unVehicleFactory>interface ou classe abstraite avec une méthode de création de véhicules.
  • Implanter des usines à béton : Implémenter des classes d'usine concrètes (TwoWheelerFactory>etFourWheelerFactory>) qui mettent en œuvre leVehicleFactory>interface et fournir des méthodes pour créer des instances de types spécifiques de véhicules.
  • Client de refactorisation : Modifier leClient>classe pour accepter unVehicleFactory>instance au lieu d’instancier directement les véhicules. Le client demandera un véhicule à l'usine, éliminant ainsi le besoin d'une logique conditionnelle basée sur les types de véhicules.
  • Flexibilité améliorée : Avec cette approche, l'ajout de nouveaux types de véhicules est aussi simple que la création d'une nouvelle classe d'usine pour le nouveau type de véhicule sans modifier le code client existant.

2. Avec modèle de conception de méthode d'usine

Décomposons le code en code par composant :

UsineMéthodeConceptionModèle

1. Interface produit

Java
// Product interface representing a vehicle public abstract class Vehicle {  public abstract void printVehicle(); }>

2. Produits en béton

Java
// Concrete product classes representing different types of vehicles public class TwoWheeler extends Vehicle {  public void printVehicle() {  System.out.println('I am two wheeler');  } } public class FourWheeler extends Vehicle {  public void printVehicle() {  System.out.println('I am four wheeler');  } }>

3. Interface du créateur (interface d'usine)

Java
// Factory interface defining the factory method public interface VehicleFactory {  Vehicle createVehicle(); }>

4. Créateurs de béton (usines à béton)

Java
// Concrete factory class for TwoWheeler public class TwoWheelerFactory implements VehicleFactory {  public Vehicle createVehicle() {  return new TwoWheeler();  } } // Concrete factory class for FourWheeler public class FourWheelerFactory implements VehicleFactory {  public Vehicle createVehicle() {  return new FourWheeler();  } }>

Code complet de cet exemple :

Java
// Library classes abstract class Vehicle {  public abstract void printVehicle(); } class TwoWheeler extends Vehicle {  public void printVehicle() {  System.out.println('I am two wheeler');  } } class FourWheeler extends Vehicle {  public void printVehicle() {  System.out.println('I am four wheeler');  } } // Factory Interface interface VehicleFactory {  Vehicle createVehicle(); } // Concrete Factory for TwoWheeler class TwoWheelerFactory implements VehicleFactory {  public Vehicle createVehicle() {  return new TwoWheeler();  } } // Concrete Factory for FourWheeler class FourWheelerFactory implements VehicleFactory {  public Vehicle createVehicle() {  return new FourWheeler();  } } // Client class class Client {  private Vehicle pVehicle;  public Client(VehicleFactory factory) {  pVehicle = factory.createVehicle();  }  public Vehicle getVehicle() {  return pVehicle;  } } // Driver program public class GFG {  public static void main(String[] args) {  VehicleFactory twoWheelerFactory = new TwoWheelerFactory();  Client twoWheelerClient = new Client(twoWheelerFactory);  Vehicle twoWheeler = twoWheelerClient.getVehicle();  twoWheeler.printVehicle();  VehicleFactory fourWheelerFactory = new FourWheelerFactory();  Client fourWheelerClient = new Client(fourWheelerFactory);  Vehicle fourWheeler = fourWheelerClient.getVehicle();  fourWheeler.printVehicle();  } }>
Sortir
I am two wheeler I am four wheeler>

Dans le code ci-dessus :

enum tostring java
  • Vehicle> sert d'interface produit, définissant la méthode commune printVehicle()> que tous les produits en béton doivent mettre en œuvre.
  • TwoWheeler> et FourWheeler> sont des classes de produits concrètes représentant différents types de véhicules, mettant en œuvre le printVehicle()> méthode.
  • VehicleFactory> fait office d'interface Creator (Factory Interface) avec une méthode createVehicle()> représentant la méthode d'usine.
  • TwoWheelerFactory> et FourWheelerFactory> sont des classes de créateurs de béton (Concrete Factories) implémentant le VehicleFactory> interface pour créer des instances de types spécifiques de véhicules.

Cas d'utilisation du modèle de conception de méthode d'usine

Voici quelques applications courantes du modèle de conception de méthode d'usine :

  • Cadres de création :
    • JDBC (Java Database Connectivity) utilise largement les usines pour créer des connexions, des instructions et des jeux de résultats. Les frameworks d'injection de dépendances comme Spring et Guice s'appuient fortement sur les usines pour créer et gérer les beans.
  • Boîtes à outils GUI :
    • Swing et JavaFX utilisent des usines pour créer des composants d'interface utilisateur tels que des boutons, des champs de texte et des étiquettes, permettant une personnalisation et une flexibilité dans la conception de l'interface utilisateur.
  • Cadres de journalisation :
    • Les frameworks de journalisation tels que Log4j et Logback utilisent des usines pour créer des enregistreurs avec différentes configurations, permettant de contrôler les niveaux de journalisation et les destinations de sortie.
  • Sérialisation et désérialisation :
    • Les frameworks de sérialisation d'objets utilisent souvent des usines pour créer des objets à partir de données sérialisées, prenant en charge différents formats de sérialisation et de versionnage.
  • Systèmes de plugins :
    • Les systèmes basés sur des plugins utilisent souvent des usines pour charger et créer des instances de plugin de manière dynamique, permettant ainsi l'extensibilité et la personnalisation.
  • Développement de jeu:
    • Les moteurs de jeu utilisent souvent des usines pour créer différents types d'objets, de personnages et de niveaux de jeu, favorisant ainsi l'organisation et la flexibilité du code.
  • Développement web:
    • Les frameworks Web utilisent parfois des usines pour créer des composants de vue, des contrôleurs et des services, permettant ainsi la modularité et la testabilité des applications Web.

Avantages du modèle de conception de méthode d'usine

Les avantages du modèle de conception de méthode d’usine sont :

sélectionner parmi plusieurs tables SQL
  • Découplage : Il sépare la logique de création d'objets du code client qui utilise ces objets. Cela rend le code plus flexible et maintenable car les modifications apportées au processus de création ne nécessitent pas de modifications du code client.
  • Extensibilité: Il est facile d’introduire de nouveaux types de produits sans modifier le code client. Il vous suffit de créer une nouvelle sous-classe Concrete Creator et d'implémenter la méthode d'usine pour produire le nouveau produit.
  • Testabilité : Il simplifie les tests unitaires en vous permettant de simuler ou de supprimer la création de produits pendant les tests. Vous pouvez tester différentes implémentations de produits de manière isolée sans vous fier à la création réelle d'objets.
  • Réutilisabilité du code : La méthode factory peut être réutilisée dans différentes parties de l'application où la création d'objets est nécessaire. Cela favorise la centralisation et la réutilisation des logiques de création d’objets.
  • Encapsulation : Il masque les classes de produits concrètes du code client, rendant le code moins dépendant d'implémentations spécifiques. Cela améliore la maintenabilité et réduit le couplage.

Inconvénients du modèle de conception de méthode d'usine

Les inconvénients du modèle de conception de méthode d'usine sont :

  • Complexité accrue : Il introduit des classes et des interfaces supplémentaires, ajoutant une couche d'abstraction qui peut rendre le code plus complexe à comprendre et à maintenir, en particulier pour ceux qui ne connaissent pas le modèle.
  • Aérien: L'utilisation du polymorphisme et de la liaison dynamique peut avoir un léger impact sur les performances, bien que cela soit souvent négligeable dans la plupart des applications.
  • Couplage étroit au sein des hiérarchies de produits : Les créateurs de béton sont toujours étroitement liés à leurs produits en béton correspondants. Les changements apportés à l’un nécessitent souvent des changements apportés à l’autre.
  • Dépendance aux sous-classes concrètes : Le code client dépend toujours de la classe abstraite Creator, nécessitant la connaissance de ses sous-classes concrètes pour effectuer des appels de méthode d'usine corrects.
  • Potentiel de surutilisation : Il est important d’utiliser le modèle Factory Method judicieusement pour éviter une ingénierie excessive de l’application. La création d'objets simples peut souvent être gérée directement sans avoir recours à une usine.
  • Défis des tests : Tester la logique de l’usine elle-même peut être plus complexe.