Eine einfache Fabrik ist kein Designmuster. Es entkoppelt einfach die Objekterstellung vom Clientcode. Mit anderen Worten: Simple Factory kapselt die Objektinstanziierung, indem die Instanziierungslogik in eine separate Klasse verschoben wird.
Einfache Fabrik wird oft mit Fabrikmuster verwechselt. Wir werden Simple Factory untersuchen, um ihre Unterschiede zu verdeutlichen. Außerdem hilft uns das Erlernen der Simple Factory, Factory-Muster leichter zu verstehen.
Eine Programmierung zur konkreten Umsetzung sollte vermieden werden, da die Wartung einer Anwendung dadurch sehr schwierig wird. Es ist immer vorzuziehen, auf die Schnittstelle zu programmieren. Wenn Sie eine konkrete Klasse im Client-Code instanziieren, ist Simple Factory praktisch, da Simple Factory die Objekterstellung vom Client entkoppeln kann. Dies macht unsere Anwendung erweiterbarer und wartbarer.
Wir entwickeln ein System für einen Burgerladen. Das System muss verschiedene Burger wie Beef-Burger, Chicken-Burger usw. erstellen.
Unser erster Versuch würde so aussehen:
// Client orders a burger Burger orderBurger(String type) { Burger burger; if (type.equals("beef")) { burger = new BeefBurger(); } else if (type.equals("chicken")) { burger = new ChickenBurger(); } else if (type.equals("fish")) { burger = new FishBurger(); } burger.prepareBun(); burger.grillPatty(); burger.addToppings(); burger.wrap(); return burger; }
Das Problem ist, dass wir für die Implementierung und nicht für die Schnittstelle programmieren. Wo? Wir verwenden die if-Anweisung und instanziieren eine konkrete Klasse basierend auf einem Burger-Typ.
Warum ist es das Problem? Unser Client-Code ist eng mit der Objekterstellung verknüpft, was zu weniger Flexibilität führt!! Nehmen wir an, wir verkaufen keine Fischburger mehr und beginnen stattdessen mit dem Verkauf von Veggie-Burgern. Wir müssen unseren Client-Code besuchen und ihn ändern. Das heißt, es ist nicht zur Änderung geschlossen.
Um das Problem zu lösen, können wir eine separate Klasse erstellen, die nur für die Objekterstellung verantwortlich ist. Dann muss sich unser Client-Code nicht um die Objekterstellung kümmern und kann sich auf die Abstraktion verlassen. Diese Technik ist bekannt als „Einkapseln, was variiert“. Wir gehen davon aus, dass der Code zum Instanziieren konkreter Objekte häufig geändert wird, während die Prozesse PrepareBun(), GrillPatty(), AddToppings() und Wrap() wahrscheinlich in Zukunft bei allen Burgern gleich bleiben werden.
Der Vorteil von Simple Factory besteht darin, dass es von anderen Klassen wiederverwendet werden kann. Möglicherweise haben wir andere Client-Klassen wie BurgerRestaurant, BurgerCateringShop, die die Methode SimpleBurgerFactory.createBurger() verwenden.
Kunde
Der Client instanziiert ein bestimmtes Burger-Objekt über SimpleBurgerFactory. Beachten Sie, dass wir aus Client-Perspektive nicht wissen, welcher konkrete Burger erstellt wird, d. h. die Objekterstellungslogik ist jetzt vom Client entkoppelt.
SimpleBurgerFactory
Diese Klasse kapselt, was variiert, in diesem Fall die Objekterstellungslogik! createBurger() wird als statische Methode deklariert, da der Client diese Klasse zum Instanziieren eines Objekts verwenden möchte (natürlich können wir keine Instanz haben, bevor wir es instanziieren!). createBurger() akzeptiert die BurgerType-Aufzählung, um zu bestimmen, welche Art von Burger erstellt werden soll.
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.
// Client orders a burger Burger orderBurger(String type) { Burger burger; if (type.equals("beef")) { burger = new BeefBurger(); } else if (type.equals("chicken")) { burger = new ChickenBurger(); } else if (type.equals("fish")) { burger = new FishBurger(); } burger.prepareBun(); burger.grillPatty(); burger.addToppings(); burger.wrap(); return burger; }
public enum BurgerType { BEEF, CHICKEN, FISH, VEGGIE }
// Abstract Product public abstract class Burger { public BurgerType burgerType; public List<String> toppings = new ArrayList<>(); public void prepareBun() { System.out.println("Preparing a bun"); } public void grillPatty() { if (burgerType == null) { throw new IllegalStateException("pattyType is undefined"); } System.out.println("Grill a " + burgerType + " patty"); } public void addToppings() { for (String item : toppings) { System.out.println("Add " + item); } } public void wrap() { System.out.println("Wrap a burger up"); } }
// Concrete product public class BeefBurger extends Burger { public BeefBurger() { burgerType = BurgerType.BEEF; List<String> items = List.of("lettuce", "pickle slices", "tomato slice", "BBQ sauce"); toppings.addAll(items); } }
// Concrete product public class VeggieBurger extends Burger { public VeggieBurger() { burgerType = BurgerType.VEGGIE; List<String> items = List.of("smoked paprika", "garlic chips", "crushed walnuts", "veggie sauce"); toppings.addAll(items); } // Concrete product can implement specific behavior that differs from other products @Override public void wrap() { System.out.println("Wrapping paper shouldn't print any meats but vegetables"); } }
// Simple factory, responsible for instantiating an object public class SimpleBurgerFactory { public static Burger createBurger(BurgerType type) { return switch (type) { case BEEF -> new BeefBurger(); case CHICKEN -> new ChickenBurger(); case FISH -> new FishBurger(); case VEGGIE -> new VeggieBurger(); default -> throw new IllegalArgumentException("unknown burger type"); }; } }
Ausgabe:
public class Client { public static void main(String[] args) { Burger burger = orderBurger(BurgerType.VEGGIE); System.out.println(burger); // Check if the object is actually veggie burger } public static 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; } }
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 vonEinfache Fabrik. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!