Modèle de création : méthode d'usine

Dec 04 2022
Cet article explique comment les classes dérivées peuvent utiliser leurs constructeurs pour créer des objets appropriés. Qu'est-ce que c'est? Une usine de logiciels crée des objets et une usine produisant des biens du monde réel produit des biens.

Cet article explique comment les classes dérivées peuvent utiliser leurs constructeurs pour créer des objets appropriés.

Qu'est-ce que c'est?

Une usine de logiciels crée des objets et une usine produisant des biens du monde réel produit des biens. Par exemple, la création d'objets en Java se passe généralement comme ceci :

Le problème avec cette approche est que, soudainement, le code utilisant l' objet SomeClass devient dépendant de l'implémentation concrète de SomeClass . Il n'y a rien de mal à créer de nouveaux objets, mais cette approche peut conduire à coupler étroitement notre code à la classe d'implémentation concrète. Cela viole le code vers une interface et non vers une implémentation.

La méthode factory est un modèle de conception de classe qui fournit une interface pour créer des objets, mais laisse les sous-classes décider quelle classe instancier.

Diagramme de classe

Le diagramme de classes comprend les éléments suivants :

  • Produit
  • Produit en béton
  • Créateur
  • Créateur de béton

En continuant avec notre exemple d'avion, supposons que nous essayons de modéliser l'avion de chasse F-16. Le code client doit construire un objet moteur pour cet avion et le piloter. Une implémentation naïve pour cette classe serait quelque chose comme ci-dessous :

Dans le code ci-dessus, nous nous sommes engagés à utiliser une implémentation concrète de la classe F16. Que se passe-t-il si l'entreprise propose des versions plus récentes de l'avion et que nous sommes tenus de les représenter dans notre programme ? Cela signifierait changer le code client où nous créons une instance F16. Une solution consiste à encapsuler la création d'objet dans un autre objet uniquement responsable de la création des variantes demandées du F-16. Pour commencer, disons que nous voulons représenter les variantes A et B de F16 ; notre code pourrait ressembler à ceci :

Une usine simple est un idiome de programmation simple qui ne crée pas d'objet usine. La méthode make peut être rendue statique pour éviter de créer un objet inutile. Cependant, comme les méthodes statiques ne peuvent pas être remplacées dans les sous-classes, nous ne pourrons pas utiliser cette usine simple comme base pour une hiérarchie de classes abstraites.

Cependant, nous souhaitons conserver la création de pièces d'objet F16 dans la même classe et pouvoir introduire de nouvelles variantes F16 au fur et à mesure de leur apparition. Dans ce cas, nous pourrions sous-classer F16 et déléguer la création du bon objet variante F16 à la sous-classe gérant cette variante. C'est précisément ainsi que fonctionne le modèle de méthode d'usine ! La méthode d'usine ici est makeF16() qui créera une nouvelle variante F16 lorsqu'elle sera appelée. En avançant, nous introduisons deux sous-classes comme ceci

Nous avons sous-classé et spécialisé l'objet moteur en utilisant l'héritage. Une méthode de fabrique peut ou non fournir une implémentation par défaut ou générique ; cependant, nous pouvons toujours le remplacer dans les sous-classes pour spécialiser ou modifier le produit. Notre exemple a deux variantes de modèles, chacune avec un moteur différent mais le même cockpit. Le code client peut désormais utiliser les nouveaux modèles comme suit :

Notez que le modèle de conception de méthode de fabrique renvoie un type abstrait, soit une interface Java, soit une classe abstraite Java. La superclasse, dans notre cas F16, ne sait pas quel type spécifique de F16 elle a été renvoyée par la méthode makeF16(). En général, une méthode de création est soit abstraite, soit fournie avec une implémentation par défaut invoquée par les autres méthodes de la superclasse. C'est donc aux sous-classes de créer des types d'objets spécifiques.

Différences avec l'usine simple/statique

Le modèle de méthode d'usine est similaire à l'usine simple ou statique, mais les différences incluent que ces usines simples ne peuvent pas produire des produits variables par héritage comme le peut un modèle de méthode d'usine.

Autres exemples

Le modèle de méthode d'usine est omniprésent dans les boîtes à outils et les cadres. Le modèle peut être utilisé chaque fois qu'une classe ne sait pas à l'avance quels objets de sous-classe elle aurait besoin d'instancier. Cela se produit souvent dans la conception de framework, où les consommateurs du framework sont censés étendre les classes abstraites fournies par le framework et les fonctionnalités d'accrochage ou les créations d'objets.

L'API Java expose plusieurs méthodes de fabrique :

java.util.Calendar.getInstance()

java.util.ResourceBundle.getBundle()

java.text.NumberFormat.getInstance()

Mises en garde

  • Le modèle peut entraîner un trop grand nombre de sous-classes avec seulement des différences mineures entre elles.
  • Si une sous-classe ajoute des fonctionnalités à une super-classe, elle ne peut pas utiliser les nouvelles méthodes à moins de convertir l'objet en son type concret. Malheureusement, Downcasting peut échouer lors de l'exécution.