Salut l'ami! Aujourd'hui, nous allons continuer à étudier les modèles de conception. Dans cette leçon, nous allons parler des usines. Nous discuterons du problème que ce modèle résout et examinerons un exemple de la façon dont une usine peut vous aider à ouvrir un café. De plus, je vais vous donner 5 étapes simples pour créer une usine. Modèle de conception d'usine - 1 Pour vous assurer que nous sommes tous sur la même longueur d'onde et que vous saisirez rapidement ce concept, vous devez vous familiariser avec les sujets suivants :
  • Héritage en Java
  • Rétrécissement et élargissement des types de référence en Java
  • Interaction entre différentes classes et objets.

Qu'est-ce qu'une usine ?

Le modèle de conception d'usine vous permet de contrôler la création d'objets. Le processus de création d'un nouvel objet n'est pas super simple, mais il n'est pas non plus trop compliqué. Nous savons tous que nous avons besoin de l' newopérateur pour créer un nouvel objet. Il semble peut-être qu'il n'y a rien à contrôler ici, mais ce n'est pas vrai. Supposons que notre application ait une certaine classe qui a de nombreux descendants. Des difficultés peuvent survenir lorsqu'il est nécessaire de créer une instance d'une classe spécifique en fonction de certaines conditions. Une usine est un modèle de conception qui aide à résoudre le problème de la création de divers objets en fonction de certaines conditions. Comment est-ce pour un concept abstrait? Cela deviendra plus clair et plus précis lorsque nous examinerons l'exemple ci-dessous.

Préparons différents types de café

Supposons que nous voulions automatiser un café. Nous devons enseigner à notre programme comment faire différents types de café. Pour ce faire, nous allons créer une classe de café et quelques classes dérivées pour représenter les types de café que nous allons préparer : Americano, cappuccino, expresso et latte. Commençons par un cours de café général :

public class Coffee {
    public void grindCoffee(){
        // Grind the coffee
    }
    public void makeCoffee(){
        // Brew the coffee
    }
    public void pourIntoCup(){
        // Pour into a cup
    }
}
Ensuite, nous allons créer ses classes enfants :

public class Americano extends Coffee {}
public class Cappuccino extends Coffee {}
public class CaffeLatte extends Coffee {}
public class Espresso extends Coffee {}
Nos clients peuvent commander n'importe quel type de café. Leurs commandes doivent être transmises au programme. Cela peut être fait de plusieurs façons, par exemple en utilisant String. Mais un enumest le meilleur pour cela. Nous allons créer un enumet définir des champs enum qui correspondent aux types de café pouvant être commandés :

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("Here's your coffee! Thanks! Come again!");
        return coffee;
    }
}
La orderCoffeeméthode peut être divisée en deux parties :
  1. Création d'une instance spécifique de café dans un switchrelevé. C'est là qu'une usine fait ce qu'elle fait - créer un type spécifique en fonction des conditions.
  2. Préparation - c'est le broyage, le brassage et le versement dans une tasse.
Voici ce qu'il est important de savoir si vous devez apporter des modifications à la méthode à l'avenir :
  1. Les étapes de la préparation elle-même (broyage, infusion et versement dans une tasse) resteront inchangées (du moins on y compte).
  2. Mais l'assortiment de cafés peut changer. Peut-être qu'on commencera à faire du moka... Frappu... Mochacci... Quoi qu'il en soit, une nouvelle sorte de café.
Nous pouvons déjà être assez confiants qu'à l'avenir nous devrons apporter des modifications à l' switchénoncé de la méthode. Il est également possible que dans notre café, la orderCoffeeméthode ne soit pas le seul endroit où nous créerons différents types de café. En conséquence, des modifications devront être apportées à 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 :
  1. Nous pouvons réutiliser la logique de fabrication du café dans d'autres endroits.
  2. Si l'assortiment change, nous n'aurons pas à modifier le code partout où le café est créé. Il suffira de changer notre code en un seul endroit.
En d'autres termes, le moment est venu de créer une usine.

Installation de notre première usine

Pour ce faire, nous allons créer une nouvelle classe qui sera uniquement chargée de créer les instances nécessaires des classes de café :

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 d'usine dans sa forme la plus simple (presque). Cela aurait pu être encore plus simple si nous avions rendu la createCoffeeméthode statique. Mais alors nous perdrions deux capacités :
  1. La possibilité d'hériter SimpleCoffeeFactoryet de remplacer la createCoffeeméthode.
  2. La possibilité d'ajouter l'implémentation d'usine requise à nos classes.
Au fait, en parlant de mise en œuvre... Nous devons retourner au café et ajouter notre usine de fabrication de café.

Ajouter une usine au café

Réécrivons la classe du 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("Here's your coffee! Thanks! Come again!");
        return coffee;
    }
}
Excellent. Nous allons maintenant fournir une description concise de la structure générale du modèle de conception d'usine.

5 étapes pour ouvrir votre propre usine

Étape 1. Votre programme a une classe avec plusieurs descendants, comme dans le schéma ci-dessous : Modèle de conception d'usine - 2Étape 2. Vous créez un enumavec un champ pour chaque classe enfant :

    enum CatType {
        LION,
        TIGER,
        FLUFFY
    }
Étape 3. Construisez votre usine. Appelez-le CatFactory. Voici le code :

class CatFactory {}
Étape 4. Dans votre usine, créez une createCatméthode qui prend un CatTypeargument. Voici le code :

    class CatFactory {
        public Cat createCat(CatType type) {
            
        }
    }
Étape 5. Dans le corps de la méthode, écrivez une switchinstruction qui énumère les champs enum et crée une instance de la classe qui correspond à la enumvaleur transmise :

class CatFactory {
        public Cat createCat(CatType type) {
            Cat cat = null;
            
            switch (type) {
                case LION:
                    cat =  new Fluffy();
                    break;
                case TIGER:
                    cat = new Tiger();
                    break;
                case FLUFFY:
                    cat =  new Lion();
                    break;
            }
            
            return cat;
        }
    }
Maintenant, vous pouvez diriger une usine comme un patron. :)

Comment pratiquer

Lire c'est bien, écrire du code c'est encore mieux. Si votre nom comporte un nombre pair de lettres, essayez de créer votre propre pizzeria virtuelle. Si votre nom comporte un nombre impair de lettres, essayez de créer un bar à sushis virtuel. Si vous n'avez pas de nom, vous avez eu de la chance. Aujourd'hui, vous pouvez vous détendre.