it-swarm.com.de

Unterschiede zwischen abstraktem Fabrikmuster und Fabrikmethode

Ich weiß, dass es viele Beiträge zu den Unterschieden zwischen diesen beiden Mustern gibt, aber es gibt ein paar Dinge, die ich nicht finden kann.

Aus dem, was ich gelesen habe, sehe ich, dass das Factory-Method-Muster es Ihnen ermöglicht, zu definieren, wie ein einzelnes konkretes Produkt erstellt wird, die Implementierung jedoch vor dem Client verborgen wird, da ein generisches Produkt angezeigt wird. Meine erste Frage betrifft die abstrakte Fabrik. Ist es seine Aufgabe, Familien mit konkreten Objekten zu erstellen (die von der jeweiligen Fabrik abhängen können) und nicht nur ein einzelnes konkretes Objekt? Gibt die abstrakte Fabrik nur ein sehr großes Objekt oder viele Objekte zurück, je nachdem, welche Methode Sie aufrufen?

Meine letzten beiden Fragen beziehen sich auf ein einziges Zitat, das ich nicht vollständig verstehen kann, das ich an zahlreichen Orten gesehen habe:

Ein Unterschied zwischen den beiden ist, dass mit dem Abstract Factory-Muster a Klasse delegiert die Verantwortung von Objektinstanziierung auf ein anderes Objekt über die Zusammensetzung während die Fabrik Das Methodenmuster verwendet Vererbung und verlässt sich auf eine Unterklasse, um mit der gewünschte Objektinstanziierung.

Ich verstehe, dass das Factory-Method-Pattern über eine Creator-Schnittstelle verfügt, die den ConcreteCreator dazu veranlassen wird, zu wissen, welches ConcreteProduct instanziiert werden soll. Bedeutet das, dass Vererbung verwendet wird, um die Objektinstanziierung zu handhaben?

In Bezug auf dieses Zitat delegiert das Abstract Factory-Muster nun die Verantwortung für die Objekt-Instantiierung durch Komposition an ein anderes Objekt. Was bedeutet das? Es sieht so aus, als würde das Abstract Factory-Muster auch in meinen Augen Vererbung für den Konstruktionsprozess verwenden, aber ich lerne auch immer noch über diese Muster.

Jede Hilfe vor allem bei der letzten Frage wäre sehr dankbar. 

361
Silverbolt

Der Unterschied zwischen den beiden

Der Hauptunterschied zwischen einer "Fabrikmethode" und einer "abstrakten Fabrik" besteht darin, dass die Fabrikmethode eine Einzelmethode ist und eine abstrakte Fabrik ein Objekt ist. Ich denke, viele Leute bekommen diese beiden Begriffe verwirrt und fangen an, sie austauschbar zu verwenden. Ich erinnere mich, dass es mir schwer fiel, genau zu erfahren, was der Unterschied war, als ich sie erfuhr.

Da die Factory-Methode nur eine Methode ist, kann sie in einer Unterklasse überschrieben werden, daher die zweite Hälfte Ihres Zitats: 

... das Factory Method-Muster verwendet Vererbung und stützt sich auf eine Unterklasse um das gewünschte Objekt zu bearbeiten Instantiation.

Das Zitat geht davon aus, dass ein Objekt hier seine eigene Factory-Methode aufruft. Daher könnte das einzige, was den Rückgabewert ändern könnte, eine Unterklasse sein.

Die abstrakte Fabrik ist ein Objekt, das mehrere Fabrikmethoden enthält. Betrachten Sie die erste Hälfte Ihres Angebots:

... mit dem Abstract Factory-Muster eine Klasse delegiert die Verantwortung des Objekts Instantiierung zu einem anderen Objekt über Zusammensetzung ...

Sie sagen, dass es ein Objekt A gibt, das ein Foo-Objekt erstellen möchte. Anstatt das Foo-Objekt selbst zu erstellen (z. B. mit einer Factory-Methode), erhält es ein different -Objekt (die abstrakte Factory), um das Foo-Objekt zu erstellen.

Code-Beispiele

Um Ihnen den Unterschied zu zeigen, wird hier eine werksseitige Methode verwendet:

class A {
    public void doSomething() {
        Foo f = makeFoo();
        f.whatever();   
    }

    protected Foo makeFoo() {
        return new RegularFoo();
    }
}

class B extends A {
    protected Foo makeFoo() {
        //subclass is overriding the factory method 
        //to return something different
        return new SpecialFoo();
    }
}

Und hier ist eine abstrakte Fabrik im Einsatz:

class A {
    private Factory factory;

    public A(Factory factory) {
        this.factory = factory;
    }

    public void doSomething() {
        //The concrete class of "f" depends on the concrete class
        //of the factory passed into the constructor. If you provide a
        //different factory, you get a different Foo object.
        Foo f = factory.makeFoo();
        f.whatever();
    }
}

interface Factory {
    Foo makeFoo();
    Bar makeBar();
    Aycufcn makeAmbiguousYetCommonlyUsedFakeClassName();
}

//need to make concrete factories that implement the "Factory" interface here
398
Tom Dalling

Abstract factory erstellt eine Basisklasse mit abstrakten Methoden, die Methoden für die Objekte definieren, die erstellt werden sollen. Jede Factory-Klasse, von der die Basisklasse abgeleitet wird, kann für jeden Objekttyp eine eigene Implementierung erstellen.

enter image description here

Factory-Methode ist nur eine einfache Methode zum Erstellen von Objekten in einer Klasse. Es wird normalerweise in der Aggregatwurzel hinzugefügt (Die Order-Klasse hat eine Methode namens CreateOrderLine)

enter image description here

Abstrakte fabrik

Im folgenden Beispiel entwerfen wir eine Schnittstelle, um die Erstellung von Warteschlangen von einem Nachrichtensystem zu trennen und Implementierungen für verschiedene Warteschlangensysteme zu erstellen, ohne die Codebasis ändern zu müssen.

interface IMessageQueueFactory
{
  IMessageQueue CreateOutboundQueue(string name);
  IMessageQueue CreateReplyQueue(string name);
}

public class AzureServiceBusQueueFactory : IMessageQueueFactory
{
      IMessageQueue CreateOutboundQueue(string name)
      {
           //init queue
           return new AzureMessageQueue(/*....*/);
      }

      IMessageQueue CreateReplyQueue(string name)
      {
           //init response queue
           return new AzureResponseMessageQueue(/*....*/);
      }

}

public class MsmqFactory : IMessageQueueFactory
{
      IMessageQueue CreateOutboundQueue(string name)
      {
           //init queue
           return new MsmqMessageQueue(/*....*/);
      }

      IMessageQueue CreateReplyQueue(string name)
      {
           //init response queue
           return new MsmqResponseMessageQueue(/*....*/);
      }
}

Fabrikmethode

Das Problem bei HTTP-Servern ist, dass wir für jede Anfrage immer eine Antwort benötigen.

public interface IHttpRequest
{
    // .. all other methods ..

    IHttpResponse CreateResponse(int httpStatusCode);
}

Ohne die Factory-Methode würden die HTTP-Server-Benutzer (d. H. Programmierer) gezwungen sein, implementierungsspezifische Klassen zu verwenden, die den Zweck der IHttpRequest-Schnittstelle missachten.

Deshalb führen wir die Factory-Methode ein, damit auch die Erstellung der Antwortklasse abstrahiert wird.

Zusammenfassung

Der Unterschied besteht darin, dass der Zweck der vorgesehenen Klasse der Klasse, die eine Factory-Methode enthält, keine Objekte erstellt, während eine abstrakte Factory nur zum Erstellen von Objekten verwendet werden sollte.

Bei der Verwendung von Factory-Methoden ist Vorsicht geboten, da das LSP ( Liskov-Substitution-Prinzip ) beim Erstellen von Objekten leicht zu brechen ist.

100
jgauffin

Der Unterschied zwischen AbstractFactory- und Factory-Design-Mustern ist wie folgt:

  • Factory-Methode wird nur zum Erstellen eines Produkts verwendet, bei Abstract Factory werden Familien verwandter oder abhängiger Produkte erstellt.
  • Das Factory-Methode -Muster stellt dem Client eine Methode zum Erstellen des Objekts zur Verfügung, während im Fall von Abstract Factory eine Familie verwandter Objekte verfügbar gemacht wird, die aus diesen Factory-Methoden bestehen können.
  • Factory Method -Muster verbirgt die Konstruktion eines einzelnen Objekts, während als Abstract Factory-Methode die Konstruktion einer Familie zusammengehöriger Objekte verborgen wird. Abstrakte Fabriken werden normalerweise mit (einer Reihe von) Fabrikmethoden implementiert.
  • Das AbstractFactory - Muster verwendet die Komposition, um die Verantwortung für das Erstellen des Objekts an eine andere Klasse zu delegieren, während das Factory - Entwurfsmuster Vererbung verwendet und zum Erstellen des Objekts eine abgeleitete Klasse oder Unterklasse verwendet.
  • Die Idee hinter dem Factory Method -Muster besteht darin, dass ein Client nicht wissen kann, welche konkreten Klassen er zur Laufzeit erstellen muss, sondern nur eine Klasse abrufen soll, die die Aufgabe erledigt AbstractFactory -Muster wird am besten verwendet, wenn Ihr System mehrere Produktfamilien erstellen muss oder Sie eine Produktbibliothek bereitstellen möchten, ohne die Implementierungsdetails offenzulegen.!

Factory Method Pattern Implementierung: Factory Method UML

AbstractFactory Pattern-Implementierung:

Abstract Factory UML

83

Zusammenfassung Factory ist eine Schnittstelle zum Erstellen verwandter Produkte. Factory-Methode ist jedoch nur eine Methode. Abstract Factory kann durch mehrere Factory-Methoden implementiert werden.

Abstract Factory UML

21
Trying

Betrachten Sie dieses Beispiel zum leichteren Verständnis.  

Was bieten Telekommunikationsunternehmen? B. über Breitband, Telefon und Mobilfunk, und Sie werden aufgefordert, eine Anwendung zu erstellen, die ihre Produkte ihren Kunden anbietet.

Im Allgemeinen sollten Sie hier die Produkte erstellen, d. H. Breitband, Telefonleitung und Mobiltelefon werden durch Ihre Factory-Methode wo Sie wissen, welche Eigenschaften Sie für diese Produkte haben, und es ist ziemlich unkompliziert.

Nun will das Unternehmen seinen Kunden ein Bündel ihrer Produkte anbieten, d. H. Breitband, Telefonleitung und Mobilfunk, und hier kommt die Abstract Factory zum Spielen.

Abstract Factory ist mit anderen Worten die Zusammensetzung anderer Fabriken, die für die Herstellung ihrer eigenen Produkte verantwortlich sind, und Abstract Factory weiß, wie sie diese Produkte in Bezug auf ihre eigenen Verantwortlichkeiten sinnvoller einsetzen können.

In diesem Fall ist BundleFactory die Abstrakte Fabrik, BroadbandFactory, PhonelineFactory und MobileFactory sind Factory. Um mehr zu vereinfachen, haben diese Fabriken Factory Method , um die einzelnen Produkte zu initialisieren.

Siehe das Codebeispiel unten:

public class BroadbandFactory : IFactory {
    public static Broadband CreateStandardInstance() {
        // broadband product creation logic goes here
    }
}

public class PhonelineFactory : IFactory {
    public static Phoneline CreateStandardInstance() {
        // phoneline product creation logic goes here
    }
}

public class MobileFactory : IFactory {
    public static Mobile CreateStandardInstance() {
        // mobile product creation logic goes here
    }
}

public class BundleFactory : IAbstractFactory {

    public static Bundle CreateBundle() {
        broadband = BroadbandFactory.CreateStandardInstance();
        phoneline = PhonelineFactory.CreateStandardInstance();
        mobile = MobileFactory.CreateStandardInstance();

        applySomeDiscountOrWhatever(broadband, phoneline, mobile);
    }

    private static void applySomeDiscountOrWhatever(Broadband bb, Phoneline pl, Mobile m) {
        // some logic here
        // maybe manange some variables and invoke some other methods/services/etc.
    }
}

Hoffe das hilft.

11
Abdul Munim

Der Hauptunterschied zwischen Abstract Factory und Factory Method ist, dass Abstract Factory von Composition implementiert wird. Factory-Methode wird jedoch durch Vererbung implementiert.

Ja, Sie haben das richtig gelesen: Der Hauptunterschied zwischen diesen beiden Mustern ist die alte Zusammensetzung vs. Vererbung Debatte.

UML-Diagramme finden Sie im (GoF) Buch. Ich möchte Codebeispiele zur Verfügung stellen, weil ich denke, dass die Kombination der Beispiele aus den ersten beiden Antworten in diesem Thread eine bessere Demonstration ergibt als beide Antworten allein. Außerdem habe ich Terminologie aus dem Buch in Klassen- und Methodennamen verwendet.

Abstrakte Fabrik

  1. Der wichtigste Punkt, den Sie hier verstehen müssen, ist, dass die abstrakte Factory injiziert in den Client ist. Aus diesem Grund sagen wir, dass Abstract Factory von Composition implementiert wird. Oft würde eine Abhängigkeitsinjektion Framework diese Aufgabe ausführen. aber ein Rahmen ist nicht erforderlich für DI.
  2. Der zweite kritische Punkt ist, dass die konkreten Fabriken hier nicht Factory Method Implementierungen sind! Beispielcode für Factory Methode wird weiter unten gezeigt.
  3. Der dritte Punkt ist die Beziehung zwischen den -Produkten: in diesem Fall die Warteschlangen für abgehende Nachrichten und Antworten. Eine konkrete Factory produziert Azure-Warteschlangen, die andere MSMQ. Die GoF bezieht sich auf .__ diese Produktbeziehung als eine "Familie", und es ist wichtig, Zu wissen, dass Familie in diesem Fall keine Klassenhierarchie bedeutet.
public class Client {
    private final AbstractFactory_MessageQueue factory;

    public Client(AbstractFactory_MessageQueue factory) {
        // The factory creates message queues either for Azure or MSMQ.
        // The client does not know which technology is used.
        this.factory = factory;
    }

    public void sendMessage() {
        //The client doesn't know whether the OutboundQueue is Azure or MSMQ.
        OutboundQueue out = factory.createProductA();
        out.sendMessage("Hello Abstract Factory!");
    }

    public String receiveMessage() {
        //The client doesn't know whether the ReplyQueue is Azure or MSMQ.
        ReplyQueue in = factory.createProductB();
        return in.receiveMessage();
    }
}

public interface AbstractFactory_MessageQueue {
    OutboundQueue createProductA();
    ReplyQueue createProductB();
}

public class ConcreteFactory_Azure implements AbstractFactory_MessageQueue {
    @Override
    public OutboundQueue createProductA() {
        return new AzureMessageQueue();
    }

    @Override
    public ReplyQueue createProductB() {
        return new AzureResponseMessageQueue();
    }
}

public class ConcreteFactory_Msmq implements AbstractFactory_MessageQueue {
    @Override
    public OutboundQueue createProductA() {
        return new MsmqMessageQueue();
    }

    @Override
    public ReplyQueue createProductB() {
        return new MsmqResponseMessageQueue();
    }
}

Fabrikmethode

  1. Der wichtigste Punkt dabei ist, dass ConcreteCreatorist der Client ist. Mit anderen Worten ist der Client eine Unterklasse, deren übergeordnetes Element die factoryMethod() definiert. Aus diesem Grund sagen wir, dass Factory-Methode durch Vererbung implementiert wird.
  2. Der zweite kritische Punkt ist, sich daran zu erinnern, dass die Factory-Methode Pattern nichts weiter als eine Spezialisierung der Template-Methode Pattern ist. Die beiden Muster haben eine identische Struktur. Sie unterscheiden sich nur in ihrem Sinn. Die Factory-Methode ist kreativ (sie baut etwas .__ etwas auf), während die Template-Methode Verhalten ist (sie berechnet etwas .__ etwas).
  3. Der dritte wichtige Punkt ist, dass die Creator (Parent) Klasse ihre eigene factoryMethod() aufruft. Wenn wir anOperation() aus der übergeordneten Klasse entfernen und nur eine einzige Methode Zurücklassen, ist dies nicht mehr das Factory-Methode-Muster. Mit anderen Worten, die Factory-Methode kann nicht mit weniger als zwei Methoden in der Parent-Klasse implementiert werden. und einer muss den anderen anrufen.
public abstract class Creator {
    public void anOperation() {
        Product p = factoryMethod();
        p.whatever();
    }

    protected abstract Product factoryMethod();
}

public class ConcreteCreator extends Creator {
    @Override
    protected Product factoryMethod() {
        return new ConcreteProduct();
    }
}

Sonstiges & Verschiedene Fabrikmuster

Beachten Sie, dass die GoF zwar zwei unterschiedliche Factory-Muster definiert, diese jedoch nicht die einzigen Factory-Muster sind. Sie sind nicht unbedingt die am häufigsten verwendeten Factory-Muster. Ein berühmtes drittes Beispiel ist Josh Blochs Static Factory Pattern von Effective Java. Das Buch "Head First Design Patterns" enthält ein weiteres Muster, das Simple Factory genannt wird.

Treten Sie nicht in die Falle, dass jedes Factory-Muster mit einem GoF-Modell übereinstimmen muss.

8
jaco0646

Lassen Sie uns klarstellen, dass wir im Produktionscode meistens abstraktes Factory-Pattern verwenden, da die Klasse A mit der Schnittstelle B programmiert ist. A muss Instanzen von B erstellen. A muss also ein Factory-Objekt haben, um Instanzen von B zu erzeugen Also ist A nicht von einem konkreten Fall von B. abhängig. Hoffe, es hilft.

3
Adrian Liu

Die Unterschiede in den Motivationen verstehen): 

Angenommen, Sie bauen ein Werkzeug, in dem Sie Objekte haben, und eine konkrete Implementierung der Zusammenhänge der Objekte. Da Sie Variationen in den Objekten vorhersehen, haben Sie eine Indirektion erstellt, indem Sie die Verantwortung für das Erstellen von Objektvarianten einem anderen Objekt zuweisen (wir nennen es abstrakte Fabrik). Diese Abstraktion ist von großem Nutzen, da Sie zukünftige Erweiterungen vorhersehen, die Varianten dieser Objekte erfordern. 

Eine andere ziemlich faszinierende Motivation in dieser Gedankenreihe ist der Fall, dass alle Objekte der gesamten Gruppe eine entsprechende Variante haben. Aufgrund einiger Bedingungen wird eine der Varianten verwendet, und in jedem Fall müssen alle Objekte dieselbe Variante haben. Dies kann ein wenig intuitiv zu verstehen sein, da wir oft denken, dass der konkrete Implementierungscode niemals bricht, solange die Varianten eines Objekts einem einheitlichen einheitlichen Vertrag (Schnittstelle im weiteren Sinne) folgen. Die faszinierende Tatsache ist, dass dies nicht immer der Fall ist, insbesondere wenn das erwartete Verhalten nicht durch einen Programmiervertrag modelliert werden kann. 

Ein einfaches (die Idee von GoF entlehnt) ist, dass alle GUI-Anwendungen von einem virtuellen Monitor sprechen, der das Erscheinungsbild von MS oder Mac oder Fedora OS emuliert. Wenn beispielsweise alle Widget-Objekte wie Fenster, Schaltflächen usw. eine MS-Variante haben, mit Ausnahme einer Bildlaufleiste, die von der MAC-Variante abgeleitet ist, schlägt der Zweck des Werkzeugs fehl. 

Diese oben genannten Fälle bilden das Grundbedürfnis von Abstract Factory Pattern.

.__ Stellen Sie sich andererseits vor, Sie schreiben ein Framework, damit viele Leute verschiedene Tools (wie die oben genannten Beispiele) mit Ihrem Framework erstellen können. Bei der Idee eines Frameworks ist dies nicht unbedingt erforderlich, obwohl Sie in Ihrer Logik keine konkreten Objekte verwenden könnten. Sie setzen eher hochrangige Verträge zwischen verschiedenen Objekten und deren Interaktion. Während Sie (als Framework-Entwickler) auf einer sehr abstrakten Ebene bleiben, muss jeder Builder des Tools Ihren Framework-Konstrukten folgen. Sie (the tool builders) haben jedoch die Freiheit zu entscheiden, welches Objekt erstellt werden soll und wie alle von ihnen erstellten Objekte interagieren sollen. Im Gegensatz zum vorherigen Fall (von Abstract Factory Pattern) müssen Sie (als Framework-Ersteller) in diesem Fall nicht mit konkreten Objekten arbeiten. und kann eher auf Vertragsebene der Objekte bleiben. Im Gegensatz zum zweiten Teil der vorherigen Motivationen haben Sie oder die Werkzeugbauer niemals die Möglichkeit, Objekte aus Varianten zu mischen. Während der Framework-Code auf Vertragsniveau bleibt, ist jeder Tool-Builder (durch die Art des Falls selbst) auf die Verwendung eigener Objekte beschränkt. In diesem Fall werden Objekterstellungen an jeden Implementierer delegiert. Framework-Anbieter stellen lediglich einheitliche Methoden zum Erstellen und Zurückgeben von Objekten bereit. Solche Methoden sind für Framework-Entwickler unumgänglich, um mit ihrem Code fortzufahren, und sie haben einen speziellen Namen mit dem Namen Factory-Methode (Factory-Method-Pattern für das zugrunde liegende Muster). 

Einige Notizen: 

  • Wenn Sie mit der „Vorlagenmethode“ vertraut sind, werden Sie feststellen, dass Factory-Methoden häufig von Vorlagenmethoden aufgerufen werden, wenn Programme zu irgendeiner Form von Framework gehören. Im Gegensatz dazu sind Mustermethoden für Anwendungsprogramme häufig eine einfache Implementierung eines bestimmten Algorithmus und keine Fabrikmethode.
  • Darüber hinaus kann zur Vollständigkeit der Gedanken unter Verwendung des Rahmens (oben erwähnt), wenn ein Werkzeugbauer innerhalb jeder Fabrikmethode ein Werkzeug erstellt, anstatt ein konkretes Objekt zu erstellen, er/sie das delegieren Verantwortung für ein Abstract-Factory-Objekt, sofern der Tool-Builder Variationen der konkreten Objekte für zukünftige Erweiterungen vorsieht.

Beispielcode:

//Part of framework-code
BoardGame {
    Board createBoard() //factory method. Default implementation can be provided as well
    Piece createPiece() //factory method

    startGame(){        //template method
         Board borad = createBoard()
         Piece piece = createPiece()
         initState(board, piece)
    }
}


//Part of Tool-builder code
Ludo inherits  BoardGame {
     Board createBoard(){ //overriding of factory method
         //Option A: return new LudoBoard() //Lodu knows object creation
         //Option B: return LudoFactory.createBoard() //Lodu asks AbstractFacory
     }
….
}

//Part of Tool-builder code
Chess inherits  BoardGame {
    Board createBoard(){ //overriding of factory method
        //return a Chess board
    }
    ….
}
3
KGhatak
  1. Meine erste Frage betrifft die abstrakte Fabrik. Ist es seine Aufgabe, Familien mit konkreten Objekten zu erstellen (die von der jeweiligen Fabrik abhängen können) und nicht nur ein einzelnes konkretes Objekt? 

Ja. Die Absicht von Abstract Factory ist:

Stellen Sie eine Schnittstelle bereit, um Familien verwandter oder abhängiger Objekte zu erstellen, ohne deren konkrete Klassen anzugeben.


  1. Gibt die abstrakte Fabrik nur ein sehr großes Objekt oder viele Objekte zurück, je nachdem, welche Methode Sie aufrufen?

Idealerweise sollte ein Objekt pro Methode, die der Client aufruft, zurückgegeben werden. 

  1. Ich verstehe, dass das Factory-Method-Pattern über eine Creator-Schnittstelle verfügt, die den ConcreteCreator dazu veranlassen wird, zu wissen, welches ConcreteProduct instanziiert werden soll. Bedeutet das, dass Vererbung verwendet wird, um die Objektinstanziierung zu handhaben?

Ja. Factory-Methode verwendet Vererbung. 

  1. Abstraktes Fabrikmuster delegieren die Verantwortung für die Objektinstanzierung durch Komposition an ein anderes Objekt. Was bedeutet das?

AbstractFactory definiert eine FactoryMethod und ConcreteFactory ist für das Erstellen eines ConcreteProducts verantwortlich. Folgen Sie einfach dem Codebeispiel in diesemarticle .

Weitere Details finden Sie in verwandten SE-Beiträgen:

Was ist der grundlegende Unterschied zwischen den Fabrik- und abstrakten Fabrikmustern?

Design Patterns: Factory vs Factory Methode vs Abstrakte Fabrik

3
Ravindra babu

Um es mit minimalem Interface & sehr einfach zu gestalten, konzentrieren Sie sich bitte auf "// 1":

class FactoryProgram
    {
        static void Main()
        {
            object myType = Program.MyFactory("byte");
            Console.WriteLine(myType.GetType().Name);

            myType = Program.MyFactory("float"); //3
            Console.WriteLine(myType.GetType().Name);

            Console.ReadKey();
        }

        static object MyFactory(string typeName)
        {
            object desiredType = null; //1
            switch (typeName)
            {
                case "byte": desiredType = new System.Byte(); break; //2
                case "long": desiredType = new System.Int64(); break;
                case "float": desiredType = new System.Single(); break;
                default: throw new System.NotImplementedException();
            }
            return desiredType;
        }
    }

Hier wichtige Punkte: 1. Factory & AbstractFactory-Mechanismen müssen Vererbung verwenden (System.Object-> Byte, Float ...); Wenn Sie also eine Vererbung im Programm haben, ist Factory (Design Factory wäre wahrscheinlich höchstwahrscheinlich nicht dort) von Entwurf 2 bereits vorhanden. Im abstrakten Werksrückgabetyp wäre eine Schnittstelle.

interface IVehicle { string VehicleName { get; set; } }
interface IVehicleFactory
    {
        IVehicle CreateSingleVehicle(string vehicleType);
    }
class HondaFactory : IVehicleFactory
    {
        public IVehicle CreateSingleVehicle(string vehicleType)
        {
            switch (vehicleType)
            {
                case "Sports": return new SportsBike();
                case "Regular":return new RegularBike();
                default: throw new ApplicationException(string.Format("Vehicle '{0}' cannot be created", vehicleType));
            }
        }
    }
class HeroFactory : IVehicleFactory
    {
        public IVehicle CreateSingleVehicle(string vehicleType)
        {
            switch (vehicleType)
            {
                case "Sports":  return new SportsBike();
                case "Scooty": return new Scooty();
                case "DarkHorse":return new DarkHorseBike();
                default: throw new ApplicationException(string.Format("Vehicle '{0}' cannot be created", vehicleType));
            }
        }
    }

class RegularBike : IVehicle { public string VehicleName { get { return "Regular Bike- Name"; } set { VehicleName = value; } } }
class SportsBike : IVehicle { public string VehicleName { get { return "Sports Bike- Name"; } set { VehicleName = value; } } }
class RegularScooter : IVehicle { public string VehicleName { get { return "Regular Scooter- Name"; } set { VehicleName = value; } } }
class Scooty : IVehicle { public string VehicleName { get { return "Scooty- Name"; } set { VehicleName = value; } } }
class DarkHorseBike : IVehicle { public string VehicleName { get { return "DarkHorse Bike- Name"; } set { VehicleName = value; } } }

class Program
{
    static void Main(string[] args)
    {
        IVehicleFactory honda = new HondaFactory(); //1
        RegularBike hondaRegularBike = (RegularBike)honda.CreateSingleVehicle("Regular"); //2
        SportsBike hondaSportsBike = (SportsBike)honda.CreateSingleVehicle("Sports");
        Console.WriteLine("******* Honda **********"+hondaRegularBike.VehicleName+ hondaSportsBike.VehicleName);

        IVehicleFactory hero = new HeroFactory();
        DarkHorseBike heroDarkHorseBike = (DarkHorseBike)hero.CreateSingleVehicle("DarkHorse");
        SportsBike heroSportsBike = (SportsBike)hero.CreateSingleVehicle("Sports");
        Scooty heroScooty = (Scooty)hero.CreateSingleVehicle("Scooty");
        Console.WriteLine("******* Hero **********"+heroDarkHorseBike.VehicleName + heroScooty.VehicleName+ heroSportsBike.VehicleName);

        Console.ReadKey();
    }
}

Wichtige Punkte: 1. Voraussetzung: Honda würde "Regular", "Sports" erstellen, aber Hero würde "DarkHorse", "Sports" und "Scooty" erstellen. 2. Warum zwei Schnittstellen? Einen für den Herstellertyp (IVehicleFactory) und einen für die Produktfabrik (IVehicle); Eine andere Möglichkeit, 2 Schnittstellen zu verstehen, ist abstrakt. In der Fabrik geht es darum, verwandte Objekte zu erstellen. 2. Der Haken ist, dass die Kinder der IVehicleFactory zurückkehren und IVehicle (anstelle von Beton in der Fabrik). so bekomme ich Elternvariable (IVehicle); dann erstelle ich den konkreten konkreten Typ, indem ich CreateSingleVehicle aufrufe und dann das übergeordnete Objekt in das tatsächliche untergeordnete Objekt umwandle. Was würde passieren, wenn ich RegularBike heroRegularBike = (RegularBike)hero.CreateSingleVehicle("Regular"); mache? Sie erhalten ApplicationException und deswegen brauchen wir eine generische abstrakte Factory, die ich Ihnen bei Bedarf erklären würde. Ich hoffe es hilft vom Anfänger bis zum Zwischenpublikum.

2
Saurabh

Beispiel aus dem wirklichen Leben. (Leicht zu erinnern)

Fabrik

Stellen Sie sich vor, Sie bauen ein Haus und nähern sich einem Schreiner für eine Tür. Sie geben das Maß für die Tür und Ihre Anforderungen an, und er wird eine Tür für Sie bauen. In diesem Fall ist der Schreiner eine Fabrik für Türen. Ihre Angaben sind Eingaben für die Fabrik, und die Tür ist die Ausgabe oder das Produkt von der Fabrik.

Abstrakte Fabrik

Betrachten Sie nun dasselbe Beispiel der Tür. Sie können zu einem Schreiner gehen, oder Sie können zu einem Geschäft mit Kunststofftüren oder einem PVC-Geschäft gehen. Alle von ihnen sind Türfabriken. Je nach Situation entscheiden Sie, an welche Art von Fabrik Sie sich wenden müssen. Das ist wie eine abstrakte Fabrik.

Ich habe hier sowohl das Factory-Methodenmuster als auch das abstrakte Factory-Muster erklärt, indem ich sie nicht verwendet habe, um Probleme zu erklären, und dann Probleme mithilfe der obigen Muster gelöst habe https://github.com/vikramnagineni/Design-Patterns/tree/master

Ich würde Abstract Factory gegenüber Factory Method jederzeit vorziehen. In Tom Dallings Beispiel (großartige Erklärung) ist zu sehen, dass Abstract Factory insofern besser zusammensetzbar ist, als dass wir lediglich eine andere Factory an den Konstruktor übergeben müssen (Konstruktorabhängigkeitspritze wird hier verwendet). Factory-Methode erfordert jedoch die Einführung einer neuen Klasse (mehr zu verwaltende Dinge) und die Verwendung von Unterklassen. Ziehe immer die Zusammensetzung der Vererbung vor. 

0
he9lin

Factory-Methode basiert auf Vererbung: Die Objekterstellung wird an Unterklassen delegiert, die die Factory-Methode zum Erstellen von Objekten implementieren.

Abstract Factorybasiert auf der Objektzusammensetzung: Die Objekterstellung wird in Methoden implementiert, die in der Factory-Schnittstelle verfügbar gemacht werden.

High-Level-Diagramm der Fabrik und abstrakte Fabrik Muster,

diagram

Weitere Informationen zur Factory-Methode finden Sie in diesem Artikel .

Weitere Informationen zur Abstract-Factory-Methode finden Sie in diesem Artikel .

0
user2266614

lassen Sie mich es genau sagen. Die meisten Antworten wurden bereits erläutert und mit Diagrammen und Beispielen versehen. Meine Antwort wäre also nur ein Liner. meine eigenen Worte: - “abstract factory pattern fügt die abstrakte Ebene über mehrere Implementierungen von Factory-Methoden hinzu. bedeutet abstrakte Fabrik enthält oder zusammengesetzt ein oder mehr als eine Fabrikmethode. “

0
King

Viele der oben genannten Antworten bieten keine Code-Vergleiche zwischen abstrakten Fabrik- und Fabrikmethode-Mustern. Im Folgenden ist mein Versuch, es über Java zu erklären. Hoffe, es hilft jemandem, der eine einfache Erklärung benötigt.

Wie GoF treffend sagt: Abstract Factory bietet eine Schnittstelle zum Erstellen von Familien verwandter oder abhängiger Objekte ohne Angabe von ihre konkreten Klassen.

        public class Client {
            public static void main(String[] args) {
               ZooFactory zooFactory = new HerbivoreZooFactory();       
               Animal animal1 = zooFactory.animal1();
               Animal animal2 = zooFactory.animal2();
               animal1.sound();
               animal2.sound();

               System.out.println();

               AnimalFactory animalFactory = new CowAnimalFactory();
               Animal animal = animalFactory.createAnimal();
               animal.sound();
            }
        }

        public interface Animal {
            public void sound();
        }

        public class Cow implements Animal {

            @Override
            public void sound() {
                System.out.println("Cow moos");
            }

        }

        public class Deer implements Animal {

            @Override
            public void sound() {
                System.out.println("Deer grunts");
            }

        }

        public class Hyena implements Animal {

            @Override
            public void sound() {
                System.out.println("Hyena.Java");
            }

        }

        public class Lion implements Animal {

            @Override
            public void sound() {
                System.out.println("Lion roars");
            }

        }

        public interface ZooFactory {
            Animal animal1();

            Animal animal2();
        }

        public class CarnivoreZooFactory implements ZooFactory {

            @Override
            public Animal animal1() {
                return new Lion();
            }

            @Override
            public Animal animal2() {
                return new Hyena();
            }

        }

        public class HerbivoreZooFactory implements ZooFactory{

            @Override
            public Animal animal1() {
                return new Cow();
            }

            @Override
            public Animal animal2() {
                return new Deer();
            }

        }

        public interface AnimalFactory {
            public Animal createAnimal();
        }

        public class CowAnimalFactory implements AnimalFactory{

            @Override
            public Animal createAnimal() {
                return new Cow();
            }

        }

        public class DeerAnimalFactory implements AnimalFactory{

            @Override
            public Animal createAnimal() {
                return new Deer();
            }

        }

        public class HyenaAnimalFactory implements AnimalFactory{

            @Override
            public Animal createAnimal() {
                return new Hyena();
            }

        }

        public class LionAnimalFactory implements AnimalFactory{

            @Override
            public Animal createAnimal() {
                return new Lion();
            }

        }
0
Jatin Shashoo

Abstrakte Fabrik : Eine Fabrik der Fabriken; eine Fabrik, die die einzelnen, aber verbundenen/abhängigen Fabriken zusammenfasst, ohne ihre konkreten Klassen anzugeben. Beispiel einer abstrakten Fabrik

Factory : Hiermit können Sie die Instanziierungslogik an untergeordnete Klassen delegieren. Factory Pattern Beispiel

0
Atul Jain