„Wenn ein Arbeiter seine Arbeit gut machen will, muss er zuerst seine Werkzeuge schärfen.“ – Konfuzius, „Die Gespräche des Konfuzius. Lu Linggong“
Titelseite > Programmierung > Einfache Fabrik

Einfache Fabrik

Veröffentlicht am 17.11.2024
Durchsuche:739

Was ist Simple Factory?

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.

Welches Problem kann eine einfache Fabrik lösen?

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.

Problem

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.

Lösung

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.

Simple Factory

  1. 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.

  2. 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.

  3. Burger
    Diese abstrakte Klasse stellt eine gemeinsame Schnittstelle für alle Burger bereit und definiert Standardverhalten.

  4. Burger-Unterklassen
    Hier sind unsere Betonprodukte. Sie können spezifisches Verhalten implementieren, indem sie Methoden überschreiben, solange sie die Burger-Klasse erweitern.

Struktur

Simple Factory

Code

public enum BurgerType {
    BEEF,
    CHICKEN,
    FISH,
    VEGGIE
}
// Abstract Product
public abstract class Burger {

    public BurgerType burgerType;
    public List 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 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 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");
        };
    }
}
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

Fallstricke

  • Entscheidungscode für die Objektinstanziierung kann manchmal komplexer sein. In einem solchen Fall könnten wir stattdessen auch die Factory-Methode in Betracht ziehen.

Vergleich mit Fabrikmuster

  • In der einfachen Fabrik gibt es normalerweise eine Fabrikklasse, die entscheidet, welcher Produkttyp erstellt werden soll, während im Fabrikmuster mehrere Fabriken eingeführt werden können.
  • Einfache Factory verwendet häufig eine statische Methode zum Erstellen von Objekten, was den Aufruf erleichtert, die Erweiterung jedoch erschwert. Andererseits verwendet die Factory-Methode eine abstrakte Methode in der Superklasse, die als Schnittstelle für alle Factorys fungiert und Unterklassen eine konkrete Implementierung für die Objektinstanziierung bereitstellt.

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 :)

Freigabeerklärung Dieser Artikel ist abgedruckt unter: https://dev.to/sota_333ad4b72095606ab40c/simple-factory-3bnl?1 Bei Verstößen wenden Sie sich bitte an [email protected], um ihn zu löschen
Neuestes Tutorial Mehr>

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