Heim  >  Artikel  >  Java  >  Fabrikmuster

Fabrikmuster

Linda Hamilton
Linda HamiltonOriginal
2024-11-20 01:01:03578Durchsuche

Was ist ein Factory-Muster?

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.

Wann sollte man es verwenden?

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)

Problem

Wenn Sie Simple Factory nicht kennen, empfehle ich Ihnen, es vorher zu studieren. Es gibt viele Ressourcen, aber mein Blog ist hier.

Factory Pattern

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.

Lösung

Factory Pattern

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

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

  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

Factory Pattern

Implementierung in Java

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

Fallstricke

  • Komplex zu implementieren, da wir viele Klassen erstellen müssen, die den Abstract-Ersteller oder das Abstract-Produkt erweitern.

Vergleich mit Simple Factory

  • 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 vonFabrikmuster. 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
Vorheriger Artikel:Variadische Funktionen in JavaNächster Artikel:Variadische Funktionen in Java