Salut mon ami! Aujourd'hui, nous continuerons à étudier les modèles de conception avec vous. Dans cette conférence, nous parlerons de l'Usine. Nous discuterons avec vous du problème résolu à l'aide de ce modèle et examinerons un exemple de la façon dont une usine aide à ouvrir un café. Et je vais également vous donner 5 étapes simples pour créer une usine. Pour être sur la même longueur d’onde avec tout le monde et en saisir facilement l’essentiel, vous devez être familier avec les sujets suivants :
- Héritage en Java
- Rétrécissement et expansion des types de référence en Java
- Interaction entre différentes classes et objets
Qu'est-ce qu'une usine ?
Le design pattern Factory vous permet de contrôler la création d’objets. Le processus de création d’un nouvel objet n’est pas si simple, mais il n’est pas non plus trop compliqué. Nous savons tous que pour créer un nouvel objet, nous devons utiliser lenew
. Et il peut sembler qu'il n'y a rien à gérer ici, mais ce n'est pas le cas. Des difficultés peuvent survenir lorsque notre application possède une certaine classe qui a de nombreux descendants et qu'il est nécessaire de créer une instance d'une certaine classe en fonction de certaines conditions. Factory est un modèle de conception qui permet de résoudre le problème de la création de différents objets en fonction de certaines conditions. Abstrait, n'est-ce pas ? Plus de spécificité et de clarté apparaîtront lorsque nous examinerons l’exemple ci-dessous.
Nous créons différents types de café
Disons que nous voulons automatiser un café. Nous devons apprendre à préparer différents types de café. Pour ce faire, dans notre application, nous allons créer une classe de café et ses dérivés : Americano, cappuccino, expresso, latte - ces types de café que nous préparerons. Commençons par le cours général de café :public class Coffee {
public void grindCoffee(){
// перемалываем кофе
}
public void makeCoffee(){
// делаем кофе
}
public void pourIntoCup(){
// наливаем в чашку
}
}
Créons ensuite ses héritiers :
public class Americano extends Coffee {}
public class Cappuccino extends Coffee {}
public class CaffeLatte extends Coffee {}
public class Espresso extends Coffee {}
Nos clients commanderont un certain type de café et cette information doit être transmise au programme. Cela peut être fait de différentes manières, par exemple en utilisant String
. Mais il est le mieux adapté à ces fins enum
. Créons enum
et définissons-y les types de café pour lesquels nous acceptons les commandes :
public enum CoffeeType {
ESPRESSO,
AMERICANO,
CAFFE_LATTE,
CAPPUCCINO
}
Super, écrivons maintenant le code de notre café :
public class CoffeeShop {
public Coffee orderCoffee(CoffeeType type) {
Coffee coffee = null;
switch (type) {
case AMERICANO:
coffee = new Americano();
break;
case ESPRESSO:
coffee = new Espresso();
break;
case CAPPUCCINO:
coffee = new Cappucсino();
break;
case CAFFE_LATTE:
coffee = new CaffeLatte();
break;
}
coffee.grindCoffee();
coffee.makeCoffee();
coffee.pourIntoCup();
System.out.println("Вот ваш кофе! Спасибо, приходите еще!");
return coffee;
}
}
La méthode orderCoffee
peut être divisée en deux composantes :
- Création d'une instance de café spécifique dans un bloc
switch-case
. C'est là que l'Usine crée un type spécifique en fonction des conditions. - La préparation elle-même est broyée, cuite et versée dans une tasse.
- L'algorithme de préparation lui-même (broyage, cuisson et versement dans une tasse) restera inchangé (du moins nous l'espérons).
- Mais la gamme de café peut changer. Peut-être que nous commencerons à faire du moka... Moka... Mokkachi... Que Dieu le bénisse, un nouveau type de café.
switch-case
. Il est également possible que dans notre café, la méthode orderCoffee
ne soit pas le seul endroit dans lequel nous créons différents types de café. Des changements devront donc être apportés à plusieurs endroits. Vous comprenez probablement déjà où je veux en venir. Nous devons refactoriser. Déplacez le bloc responsable de la création du café dans une classe distincte pour deux raisons :
- Nous pourrons réutiliser la logique de création de café dans d’autres lieux.
- Si la gamme change, nous n'aurons pas à modifier le code partout où la création de café sera utilisée. Il suffira de changer le code à un seul endroit.
Nous scions notre première usine
Pour ce faire, créons une nouvelle classe qui se chargera uniquement de créer les instances nécessaires des classes coffee :public class SimpleCoffeeFactory {
public Coffee createCoffee (CoffeeType type) {
Coffee coffee = null;
switch (type) {
case AMERICANO:
coffee = new Americano();
break;
case ESPRESSO:
coffee = new Espresso();
break;
case CAPPUCCINO:
coffee = new Cappucino();
break;
case CAFFE_LATTE:
coffee = new CaffeLatte();
break;
}
return coffee;
}
}
Toutes nos félicitations! Nous venons d'implémenter le modèle de conception Factory dans sa forme la plus simple. Même si tout pourrait être encore plus simple si la méthode était rendue createCoffee
statique. Mais alors nous perdrions deux possibilités :
- Héritez
SimpleCoffeeFactory
et remplacez lecreateCoffee
. - Implémentez l’implémentation d’usine requise dans nos classes.
Introduction d'une usine dans un café
Réécrivons notre cours de café en utilisant une usine :public class CoffeeShop {
private final SimpleCoffeeFactory coffeeFactory;
public CoffeeShop(SimpleCoffeeFactory coffeeFactory) {
this.coffeeFactory = coffeeFactory;
}
public Coffee orderCoffee(CoffeeType type) {
Coffee coffee = coffeeFactory.createCoffee(type);
coffee.grindCoffee();
coffee.makeCoffee();
coffee.pourIntoCup();
System.out.println("Вот ваш кофе! Спасибо, приходите еще!");
return coffee;
}
}
Super. Essayons maintenant de décrire de manière schématique et concise la structure du modèle de conception Factory.
5 étapes pour ouvrir votre propre usine
Étape 1. Dans votre programme vous avez une classe avec plusieurs descendants, comme dans l'image ci-dessous : Étape 2. Vous créez une classeenum
dans laquelle vous définissez une variable enum pour chaque classe descendante :
enum CatType {
LION,
TIGER,
BARSIK
}
Étape 3. Vous construisez votre usine. Vous l'appelez MyClassFactory
, le code est ci-dessous :
class CatFactory {}
Étape 4. Vous créez une méthode dans votre usine createMyClass
qui prend la variable - enum
MyClassType
. Code ci-dessous :
class CatFactory {
public Cat createCat(CatType type) {
}
}
Étape 5. Vous écrivez un bloc dans le corps de la méthode switch-case
dans lequel vous parcourez toutes les valeurs d'énumération et créez une instance de la classe correspondant à enum
la valeur :
class CatFactory {
public Cat createCat(CatType type) {
Cat cat = null;
switch (type) {
case LION:
cat = new Barsik();
break;
case TIGER:
cat = new Tiger();
break;
case BARSIK:
cat = new Lion();
break;
}
return cat;
}
}
Comme un pro.
GO TO FULL VERSION