Factory-Muster ist ein Erstellungsmuster, das eine Schnittstelle zum Erstellen eines Objekts definiert, aber Unterklassen entscheiden lässt, welche Klasse instanziiert werden soll. Mit dem Factory-Muster kann eine Klasse die Instanziierung auf Unterklassen verschieben.
Verwenden Sie das Factory-Muster, wenn Sie über eine „Produkt“-Vererbungshierarchie verfügen, und fügen Sie dieser möglicherweise weitere Produkte hinzu. (Produkt bezieht sich auf ein Objekt, das von der Factory-Methode zurückgegeben wird)
Wenn Sie Simple Factory nicht kennen, empfehle ich Ihnen, es vorher zu studieren. Es gibt viele Ressourcen, aber mein Blog ist hier.
Zuvor haben wir Simple Factory eingeführt und konnten verschiedene Burger produzieren, während wir die Objekterstellung vom Client-Code entkoppelten. Unser Burgerladen hat erfolgreich Gewinne erwirtschaftet und jetzt wollen wir weitere Burgerläden in anderen Gegenden eröffnen.
orderBurger-Methode definiert den Prozess zum Verkauf eines Burgers für einen Kunden.
// 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; } }
Das ist völlig in Ordnung, aber was wäre, wenn wir weitere Burgerläden eröffnen? Angenommen, wir starten „SeaSideBurgerShop“, erstellen die SeaSideBurgerShop-Klasse und definieren ihre eigene orderBurger(). Das Problem besteht darin, dass sie möglicherweise vergessen, Toppings hinzuzufügen, oder den Vorgang in der falschen Reihenfolge durchführen.
Problematischer 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; } }
Um dies zu verhindern, brauchen wir einen Rahmen für unsere Burgerläden, der definiert, in welcher Reihenfolge sie den Prozess durchführen und was zu tun ist, und der dennoch Flexibilität ermöglicht.
BurgerShop
Diese abstrakte Klasse verfügt über zwei Methoden: orderBurger() und createBurger(). orderBurger() definiert, was zu tun ist und in welcher Reihenfolge der Prozess durchgeführt werden soll. Dies verhindert, dass Burgerläden einen Vorgang vergessen oder die Reihenfolge des Vorgangs durcheinander bringen. creatBurger() ist eine abstrakte Methode, mit der Unterklassen bestimmen können, welche Art von Burger hergestellt wird.
BurgerShop-Unterklassen
Diese Beton-BurgerShops sind für die Herstellung von Beton-Burgern verantwortlich. Jede Unterklasse, die BurgerShop erweitert, definiert ihre eigene Implementierung für createBurger().
Burger
Diese abstrakte Klasse stellt eine gemeinsame Schnittstelle für alle Burger bereit und definiert Standardverhalten.
Burger-Unterklassen
Hier sind unsere Betonprodukte. Sie können spezifisches Verhalten implementieren, indem sie Methoden überschreiben, solange sie die Burger-Klasse erweitern.
// 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); }
Ausgabe:
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"); }; } }
Sie können alle Entwurfsmusterimplementierungen hier überprüfen.
GitHub-Repository
P.S.
Ich bin neu im Schreiben von Tech-Blogs. Wenn Sie Ratschläge zur Verbesserung meines Schreibens haben oder einen verwirrenden Punkt haben, hinterlassen Sie bitte einen Kommentar!
Vielen Dank fürs Lesen :)
Das obige ist der detaillierte Inhalt vonFabrikmuster. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!