Heim  >  Artikel  >  Java  >  Einfache Fabrik

Einfache Fabrik

Barbara Streisand
Barbara StreisandOriginal
2024-11-24 11:40:11301Durchsuche

Was ist Simple Factory?

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.

Welches Problem kann eine einfache Fabrik lösen?

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.

Problem

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.

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

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

// 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;
    }
}

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.
  • Eine einfache Fabrik 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 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!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn