Maison  >  Article  >  Java  >  Modèle d'usine

Modèle d'usine

Linda Hamilton
Linda Hamiltonoriginal
2024-11-20 01:01:03576parcourir

Qu'est-ce que le modèle d'usine ?

Le modèle d'usine est un modèle de création qui définit une interface pour créer un objet, mais laisse les sous-classes décider quelle classe instancier. Le modèle d'usine permet à une classe de différer l'instanciation aux sous-classes.

Quand l'utiliser ?

Utilisez le modèle Factory lorsque vous avez une hiérarchie d'héritage "produit" et ajoutez éventuellement d'autres produits à celle-ci. (Le produit fait référence à un objet renvoyé par la méthode Factory)

Problème

Si vous ne connaissez pas Simple Factory, je vous recommande de l'étudier au préalable. Il existe de nombreuses ressources mais mon blog est ici.

Factory Pattern

Auparavant, nous avons introduit Simple Factory et nous pouvions produire une variété de hamburgers tout en dissociant la création d'objets du code client. Notre magasin de hamburgers a réussi à réaliser des bénéfices et nous souhaitons maintenant lancer d'autres magasins de hamburgers dans différentes zones.

La méthode orderBurger définit le processus de vente d'un hamburger à un client.

// This is our Client
public class BurgerShop {

    public Burger orderBurger(BurgerType type) {
        // Factory is responsible for object creation
        Burger burger = SimpleBurgerFactory.createBurger(type);

        burger.prepareBun();
        burger.grillPatty();
        burger.addToppings();
        burger.wrap();

        return burger;
    }
}

C'est tout à fait bien, mais et si nous lancions d'autres boutiques de burger ? Disons que nous lançons "SeaSideBurgerShop", nous allons créer la classe SeaSideBurgerShop et définir sa propre orderBurger(). Le problème est qu'ils pourraient oublier d'ajouter des garnitures ou effectuer le processus dans le mauvais ordre.

Problématique SeaSideBurgerShop :

public class SeaSideBurgerShop {

    public Burger orderBurger(BurgerType type) {
        Burger burger = SimpleBurgerFactory.createBurger(type);

        burger.prepareBun();
        burger.wrap(); // Wrap a burger before grilling a patty??
        burger.grillPatty();
        // They forget to add toppings!!

        return burger;
    }
}

Pour éviter cela, nous avons besoin d'un cadre pour nos burger shops qui définissent dans quel ordre ils effectuent le processus et quoi faire, tout en permettant aux choses de rester flexibles.

Solution

Factory Pattern

  1. BurgerShop
    Cette classe abstraite a deux méthodes, orderBurger() et createBurger(). orderBurger() définit quoi faire et dans quel ordre le processus doit être effectué. Cela empêche les burger shops d'oublier un processus ou de gâcher une commande de processus. creatBurger() est une méthode abstraite qui permet aux sous-classes de déterminer quel type de hamburger sera préparé.

  2. Sous-classes de BurgerShop
    Ces BurgerShops en béton sont chargés de créer des burgers en béton. Chaque sous-classe qui étend BurgerShop définit sa propre implémentation pour createBurger().

  3. Hamburger
    Cette classe abstraite fournit une interface commune à tous les hamburgers et définit les comportements par défaut.

  4. Sous-classes de hamburgers
    Voici nos produits en béton. Ils peuvent implémenter un comportement spécifique en remplaçant les méthodes tant qu'ils étendent la classe Burger.

Structure

Factory Pattern

Implémentation en Java

// This is our Client
public class BurgerShop {

    public Burger orderBurger(BurgerType type) {
        // Factory is responsible for object creation
        Burger burger = SimpleBurgerFactory.createBurger(type);

        burger.prepareBun();
        burger.grillPatty();
        burger.addToppings();
        burger.wrap();

        return burger;
    }
}

public class SeaSideBurgerShop {

    public Burger orderBurger(BurgerType type) {
        Burger burger = SimpleBurgerFactory.createBurger(type);

        burger.prepareBun();
        burger.wrap(); // Wrap a burger before grilling a patty??
        burger.grillPatty();
        // They forget to add toppings!!

        return burger;
    }
}
public enum BurgerType {
    BEEF,
    CHICKEN,
    FISH,
    VEGGIE
}
public abstract class Burger {
    public BurgerType type;
    public List<String> toppings = new ArrayList<>();

    public void prepareBun() {
        System.out.println("Preparing a bun");
    }

    public void grillPatty() {
        if (type == null) {
            throw new IllegalStateException("pattyType is undefined");
        }
        System.out.println("Grill a " + type + " patty");
    }

    public void addToppings() {
        for (String item : toppings) {
            System.out.println("Add " + item);
        }
    }

    public void wrap() {
        System.out.println("Wrap a burger up");
    }
}
public class CityStyleBeefBurger extends Burger {

    public CityStyleBeefBurger() {
        type = BurgerType.BEEF;
        List<String> items = List.of("lettuce", "pickle slices", "tomato slice", "BBQ sauce");
        toppings.addAll(items);
    }
}
public class CityStyleVeggieBurger extends Burger {

    public CityStyleVeggieBurger() {
        type = BurgerType.VEGGIE;
        List<String> items = List.of("smoked paprika", "garlic chips", "crushed walnuts", "veggie sauce");
        toppings.addAll(items);
    }
}
public class SeaSideStyleBeefBurger extends Burger {

    public SeaSideStyleBeefBurger() {
        type = BurgerType.BEEF;
        // Localized toppings for beef burger in seaside area
        List<String> items = List.of("lettuce", "pickle slices", "tomato slice", "salty sauce");
        toppings.addAll(items);
    }

    // Uses localized wrapping paper
    @Override
    public void wrap() {
        System.out.println("Wrap with a paper with nice sea scenery");
    }
}
public class SeaSideStyleFishBurger extends Burger {

    public SeaSideStyleFishBurger() {
        type = BurgerType.FISH;
        // Localized toppings for fish burger in seaside area
        List<String> items = List.of("red onion slices", "salty sauce", "fried shrimps");
        toppings.addAll(items);
    }

    // Uses localized wrapping paper
    @Override
    public void wrap() {
        System.out.println("Wrap with a paper with nice sea scenery");
    }
}
public abstract class BurgerShop {

    // This method provides a framework for each burger shops to order burgers
    public Burger orderBurger(BurgerType type) {
        Burger burger = createBurger(type);

        burger.prepareBun();
        burger.grillPatty();
        burger.addToppings();
        burger.wrap();

        return burger;
    }

    // This is our factory method. Subclasses will override this method,
    // provide their own implementation, determine which kind of burger gets made.
    public abstract Burger createBurger(BurgerType type);
}

Sortie :

public class CityBurgerShop extends BurgerShop {

    @Override
    public Burger createBurger(BurgerType type) {
        return switch (type) {
            case BEEF -> new CityStyleBeefBurger();
            case VEGGIE -> new CityStyleVeggieBurger();
            default -> throw new IllegalArgumentException("unknown city burger type");
        };
    }
}

Pièges

  • Complexe à mettre en œuvre car nous devons créer beaucoup de classes qui étendent le créateur abstrait ou le produit abstrait.

Comparaison avec l'usine simple

  • Dans Simple Factory, il existe généralement une classe d'usine pour décider quel type de produit créer, tandis que le modèle Factory peut introduire plusieurs usines.
  • Simple Factory utilise souvent une méthode statique pour créer des objets, ce qui la rend facile à appeler mais difficile à étendre. D'autre part, la méthode Factory utilise une méthode abstraite dans la super classe, qui agit comme une interface pour toutes les usines et les sous-classes fourniront une implémentation concrète pour l'instanciation d'objets.

Vous pouvez consulter toutes les implémentations de modèles de conception ici.
Dépôt GitHub


P.S.
Je suis nouveau dans l'écriture d'un blog technique, si vous avez des conseils pour améliorer mon écriture ou si vous avez un point déroutant, veuillez laisser un commentaire !
Merci d'avoir lu :)

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn
Article précédent:Fonctions variadiques en JavaArticle suivant:Fonctions variadiques en Java