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.
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)
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.
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.
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é.
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().
Hamburger
Cette classe abstraite fournit une interface commune à tous les hamburgers et définit les comportements par défaut.
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.
// 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"); }; } }
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!