Eine einfache Fabrik ist kein Entwurfsmuster. Es entkoppelt einfach die Objekterstellung vom Clientcode. Mit anderen Worten: Die Simple Factory kapselt die Objektinstanziierung, indem sie die Instanziierungslogik in eine separate Klasse verschiebt.
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 auf eine konkrete Implementierung 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 Burger-Shop. 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 codieren. 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 „Kapseln Sie, 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.
public enum BurgerType { BEEF, CHICKEN, FISH, VEGGIE }
// Abstract Product public abstract class Burger { public BurgerType burgerType; public Listtoppings = 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; Listitems = List.of("lettuce", "pickle slices", "tomato slice", "BBQ sauce"); toppings.addAll(items); } }
// Concrete product public class VeggieBurger extends Burger { public VeggieBurger() { burgerType = BurgerType.VEGGIE; Listitems = 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"); }; } }
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; } }
Ausgabe:
Preparing a bun Grill a VEGGIE patty Add smoked paprika Add garlic chips Add crushed walnuts Add veggie sauce Wrapping paper shouldn't print any meats but vegetables com.factories.simpleFactory.VeggieBurger@9807454
Sie können hier alle Entwurfsmusterimplementierungen ü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 :)
Haftungsausschluss: Alle bereitgestellten Ressourcen stammen teilweise aus dem Internet. Wenn eine Verletzung Ihres Urheberrechts oder anderer Rechte und Interessen vorliegt, erläutern Sie bitte die detaillierten Gründe und legen Sie einen Nachweis des Urheberrechts oder Ihrer Rechte und Interessen vor und senden Sie ihn dann an die E-Mail-Adresse: [email protected] Wir werden die Angelegenheit so schnell wie möglich für Sie erledigen.
Copyright© 2022 湘ICP备2022001581号-3