Was ist der Unterschied zwischen dem Fabrikmuster und der abstrakten Fabrik?

40

Nachdem ich endlich ernsthaft angefangen habe, einige grundlegende Muster zu lernen (sehr spät in der Karriere, aber das ist eine andere Geschichte), versuche ich, mich mit den Unterschieden zwischen Factory Pattern und Abstract Factory vertraut zu machen.

Was sind die Hauptunterschiede zwischen diesen beiden Mustern?

Ich verstehe, dass die Factory-Methode Objekte durch Vererbung und Abstract Factory durch Objektkomposition erstellt, aber aus praktischer Sicht habe ich immer noch Probleme, mir genau vorzustellen, wie sie funktionieren.

Phil.Wheeler
quelle
2
Meinen Sie zur Verdeutlichung "Factory-Methode", wenn Sie "Factory-Muster" sagen? Wenn Sie über die Vierergruppen-Muster sprechen, gibt es kein Fabrikmuster, sondern abstrakte Fabrik und Fabrikmethode.
Thomas Owens
Ja - Fabrikmethode.
Phil.Wheeler
3
Um fair zu sein, scheinen die beiden Phrasen ziemlich häufig vertauscht zu sein.
Phil.Wheeler
1
Ah, Fabrikmethode. Ein Workaround für die Tatsache, dass newes sich nicht um eine Methode handelt (in einigen - zugegebenermaßen gewöhnlichen - Objektsystemen).
Donal Fellows

Antworten:

44

Die Factory-Methode wird normalerweise durch eine switch-Anweisung kategorisiert, bei der jeder Fall eine andere Klasse unter Verwendung derselben Root-Schnittstelle zurückgibt, sodass der aufrufende Code niemals Entscheidungen über die Implementierung treffen muss.

Stellen Sie sich eine Kreditkartenprüferfabrik vor, die für jeden Kartentyp einen anderen Prüfer zurückgibt.

public ICardValidator GetCardValidator (string cardType)
{
    switch (cardType.ToLower())
    {
        case "visa":
            return new VisaCardValidator();
        case "mastercard":
        case "ecmc":
            return new MastercardValidator();
        default:
            throw new CreditCardTypeException("Do not recognise this type");
    }
}

In der Abstract Factory gibt es mehrere konkrete Factory-Klassen (keine Factory-Methoden), die von einer Schnittstelle abgeleitet sind und möglicherweise viele verschiedene Typen von verschiedenen Methoden zurückgeben.

Stellen Sie sich einen Schachspielmanager mit einer anderen Klasse für jeden Satz von Variantenregeln vor.

public class StandardChessRulesFactory : IChessRulesFactory
{
    public IBoardMapper GetBoardMapper()
    {
        return new StandardChessBoardMapper();
    }

    public IKingMover GetKingMover()
    {
        return new StandardChessKingMover();
    }

    public IMoveClock GetMoveClock()
    {
        return new StandardMoveClock();
    }
}

public class HexagonalChessRulesFactory : IChessRulesFactory
{
    public IBoardMapper GetBoardMapper()
    {
        return new HexagonalChessBoardMapper();
    }

    public IKingMover GetKingMover()
    {
        return new HexagonalChessKingMover();
    }

    public IMoveClock GetMoveClock()
    {
        return new StandardMoveClock();
    }
}

public class SpeedChessRulesFactory : IChessRulesFactory
{
    public IBoardMapper GetBoardMapper()
    {
        return new StandardChessBoardMapper();
    }

    public IKingMover GetKingMover()
    {
        return new StandardChessKingMover();
    }

    public IMoveClock GetMoveClock()
    {
        return new SpeedChessMoveClock();
    }
}

Eine abstrakte Fabrik wird ähnlich wie eine Strategie häufig mit einer Fabrikmethode ausgewählt, aber es ist nicht erforderlich, sie zu kombinieren, damit es ein eigenes Muster ist.

pdr
quelle
3
Ist diese Erklärung der Factory-Methode korrekt? Was ist mit "Das Factory-Methodenmuster ist auf Vererbung angewiesen, da die Objekterstellung an Unterklassen delegiert wird , die die Factory-Methode zum Erstellen von Objekten implementieren". Das Beispiel ähnelt also eher einer statischen Fabrik.
SerG
@SerG Nun, fairerweise haben Sie dieses Zitat aus Wikipedia auf einer Seite aufgegriffen, die vor drei Jahren sehr unterschiedlich gelesen hat. Ich würde argumentieren, dass sich die aktuelle Wikipedia-Seite an mehreren Stellen widerspricht, aber ich habe nicht den Wunsch, mich darauf einzulassen. Im Nachhinein würde ich zugeben, dass das Beispiel, das ich hier angegeben habe, eine bestimmte Art von Factory-Methode ist, die als parametrisierte Factory-Methode bezeichnet wird. Der Unterschied zwischen der Factory-Methode und Abstract Factory gilt jedoch für alle Arten von Factory-Methoden.
pdr
2
Die gleiche Aussage wie mein Zitat existiert in GoF "Design Patterns". Dort wird auch das parametrierte FM beschrieben.
SerG
Der wichtige Teil ist, dass die Fabrik dem Anrufer ein geeignetes Objekt gibt, abhängig von der jeweiligen Situation, und der Anrufer muss nicht genau wissen, welche Klasse dieses Objekt hat, und muss nicht wissen, wie das jeweilige Objekt ist wurde ausgewählt, solange das Objekt eine Schnittstelle unterstützt, die dem Aufrufer bekannt ist.
gnasher729
In Ihrer Antwort sollten Sie klarstellen, dass Ihr Beispiel kein typisches Factory-Methodenmuster ist, sondern eine Spezialisierung mit dem Namen parametrisierte Factory-Methode. Und schreiben Sie über die Definition einer typischen Fabrikmethode, weil sie gerade falsch geladen wird. Ich habe gerade etwas über das Factory-Methodenmuster gelernt, habe alles verstanden und dann die Antwort gelesen, die das Factory-Methodenmuster als etwas anderes darstellt, und war verwirrt. Es gibt keine Informationen darüber, dass dieses Beispiel kein typisches Factory-Methodenmuster ist. Vielen Dank an SerG, der das im Kommentar erwähnt hat.
CTOMEK