Usine abstraite sur les doigts

J'ai été obligé d'écrire cet article pour deux raisons. Plus récemment, j'ai rencontré le modèle Abstract Factory. Comme dit le proverbe - "Je ne sais pas comment le faire toi-même, enseigne à un ami." On sait que l'un des meilleurs moyens de consolider le matériel est d'expliquer à quelqu'un qui a déjà étudié. La deuxième raison - dans le processus d'étude de ce modèle, je n'ai pas trouvé de matériel qui pour moi personnellement énoncerait clairement l'essence de la fabrique abstraite (au moins à Habré).

Commençons donc. La toute première question à laquelle vous devez répondre vous-même en étudiant ce modèle: "Qu'est-ce qu'une usine abstraite?" La réponse la plus simple et la plus précise est que l'usine abstraite est une «usine d'usines». Mais ici, une deuxième question apparaît: «Pourquoi aurait-on même besoin d'une« usine d'usines »? Pour y répondre, considérons un exemple tiré de la vie réelle.

Supposons que vous décidiez de prendre le contrôle total du marché automobile. Comment faire Vous pouvez créer votre propre marque de voiture, votre production, diriger une grande entreprise de publicité, etc. Mais, dans ce cas, vous devez vous battre avec des géants du marché automobile comme Toyota ou Ford. Ce n'est pas un fait que vous sortirez victorieux de cette lutte. Une bien meilleure solution serait de racheter les usines de toutes ces sociétés, de continuer à produire des voitures sous leurs propres marques et de mettre des bénéfices dans votre poche. Si je ne me trompe pas, une telle structure de l'économie est appelée - holding. Cette participation sera la Abstract Factory ou «Factory of Factories». Dans notre programme, la fabrique abstraite (holding) sera représentée par une interface ou une classe abstraite. Les entreprises incluses dans l'exploitation sont représentées par des classes qui mettent en œuvre cette interface.

public interface CarsFactory { } public class ToyotaFactory implements CarsFactory {} public class FordFactory implements CarsFactory {} 

Ensuite, vous rassemblez les directeurs de vos usines et dites: «Désormais, nous fabriquerons des voitures avec 2 types de carrosserie dans nos usines - une berline et un coupé. Par exemple, les Japonais feront ToyotaSedan et ToyotaCoupe, les Américains feront FordSedan et FordCoupe. » Et pour que les usines n'oublient pas exactement ce qui doit être fait et ne démarrent pas, par exemple, les SUV, nous accrocherons les dessins généraux de la berline et du coupé dans le bureau de notre exploitation dans un endroit bien en vue (dans une usine particulière, les ingénieurs trouveront comment fabriquer les voitures dont ils ont besoin). Ainsi, 2 méthodes apparaissent dans notre interface CarsFactory:

 public interface CarsFactory { Sedan createSedan(); Coupe createCoupe(); } 

Par conséquent, dans les classes enfants de l'interface CarsFactory, ces méthodes doivent également être implémentées.

 public class ToyotaFactory implements CarsFactory { @Override public Sedan createSedan() { return new ToyotaSedan(); } @Override public Coupe createCoupe() { return new ToyotaCoupe(); } } public class FordFactory implements CarsFactory { @Override public Sedan createSedan() { return new FordSedan(); } @Override public Coupe createCoupe() { return new FordCoupe(); } } 

Notez que le type de la valeur de retour dans les méthodes sera exactement le type commun aux valeurs de retour - berline et coupé. Revenons à notre analogie - vous avez dit à l'usine de fabriquer une berline - vous avez une berline. Les caractéristiques, comme une berline Ford, ne vous intéressent pas.

Comme vous pouvez facilement le deviner à partir du code ci-dessus, certaines entités devraient apparaître dans notre programme qui décrivent des types de carrosserie spécifiques - une berline et un coupé. Ces entités seront des interfaces.

 public interface Sedan {} public interface Coupe {} 

Et bien sûr, ces dessins devraient avoir un mode de réalisation spécifique sous la forme de voitures créées dans une usine particulière.

 public class ToyotaCoupe implements Coupe { public ToyotaCoupe() { System.out.println("Create ToyotaCoupe"); } } public class ToyotaSedan implements Sedan { public ToyotaSedan() { System.out.println("Create ToyotaSedan"); } } public class FordCoupe implements Coupe { public FordCoupe () { System.out.println("Create FordCoupe"); } } public class FordSedan implements Sedan { public FordSedan() { System.out.println("Create FordSedan"); } } 

C'est tout, notre «usine d'usines» capable de produire des voitures de toute marque et de tout type est prête. À l'avenir, vous pourriez décider que ce serait bien de commencer à produire des VUS. Vous devrez créer une autre interface et accrocher un dessin d'un SUV dans le bureau de l'exploitation (ajoutez la méthode requise à CarsFactory et implémentez-la dans les usines subsidiaires). Il est également possible que vous décidiez de capturer une autre partie du marché et d'acheter, par exemple, toutes les usines Nissan. Cela signifie que vous devez créer une autre classe qui implémente CarsFactory - NissanFactory, et commencer à produire vos voitures sous cette marque (NissanCoupe, NissanSedan, etc.)

Mais comment un utilisateur spécifique (acheteur de voiture) va-t-il interagir avec notre exploitation? L'acheteur ne sait généralement pas que vous avez saisi toutes les usines automobiles du monde. Il vient dans le petit bureau modeste de l'exploitation et dit: "J'ai besoin d'une voiture!" "Génial!" - on lui dit, - «tu t'es adressé à l'adresse! Une usine d'usines est ce dont vous avez besoin! »

 CarsFactory factory; 

«Quelle entreprise automobile préférez-vous à cette heure de la journée?», Demandons-nous. Supposons qu'un client veuille acheter une Toyota. Pas de problème!

 factory = new ToyotaFactory(); 

"Quel type de corps aimeriez-vous?" Disons une berline. “Excellent choix!”

 factory.createSedan(); 

La voiture est prête, vous pouvez partir!

Source: https://habr.com/ru/post/fr465835/


All Articles