Wann ist es eine gute Idee, Factory-Methoden innerhalb eines Objekts anstelle einer Factory-Klasse zu verwenden?
design-patterns
factory
factory-pattern
factory-method
Ravindra Babu
quelle
quelle
Antworten:
Ich denke gerne über Designmuster nach, wenn meine Klassen „Menschen“ sind, und die Muster sind die Art und Weise, wie die Menschen miteinander sprechen.
Für mich ist das Fabrikmuster also wie eine Personalagentur. Sie haben jemanden, der eine variable Anzahl von Arbeitern benötigt. Diese Person kennt möglicherweise einige Informationen, die sie für die von ihnen eingestellten Personen benötigt, aber das war's.
Wenn sie also einen neuen Mitarbeiter benötigen, rufen sie die Personalagentur an und sagen ihnen, was sie brauchen. Um tatsächlich jemanden einstellen zu können , müssen Sie eine Menge Dinge wissen - Vorteile, Überprüfung der Berechtigung usw. Aber die Person, die anstellt, muss nichts davon wissen - die Einstellungsagentur kümmert sich um all das.
Auf die gleiche Weise ermöglicht die Verwendung einer Factory dem Verbraucher, neue Objekte zu erstellen, ohne die Details zu kennen, wie sie erstellt wurden oder welche Abhängigkeiten sie haben - sie müssen nur die Informationen angeben, die sie tatsächlich möchten.
Jetzt kann der Verbraucher der ThingFactory eine Sache erhalten, ohne über die Abhängigkeiten der Sache Bescheid wissen zu müssen, mit Ausnahme der Zeichenfolgendaten, die vom Verbraucher stammen.
quelle
within an object instead of a Factory class
. Ich denke, er meinte das Szenario, in dem Sie den ctor privat machen und eine statische Methode verwenden, um die Klasse zu instanziieren (ein Objekt erstellen).ThingFactory
Um diesem Beispiel zu folgen, muss man zuerst die Klasse instanziieren , umThing
Objekte zu erhalten , was dies zu einemFactory class
Effekt macht.Factory-Methoden sollten als Alternative zu Konstruktoren betrachtet werden - meistens, wenn Konstruktoren nicht ausdrucksstark genug sind, d. H.
ist nicht so ausdrucksstark wie:
Factory-Klassen sind nützlich, wenn Sie einen komplizierten Prozess zum Erstellen des Objekts benötigen, wenn die Konstruktion eine Abhängigkeit benötigt, die Sie für die tatsächliche Klasse nicht benötigen, wenn Sie verschiedene Objekte usw. erstellen müssen.
quelle
Eine Situation, in der ich persönlich separate Factory-Klassen für sinnvoll halte, besteht darin, dass das endgültige Objekt, das Sie erstellen möchten, von mehreren anderen Objekten abhängt. Beispiel: In PHP: Angenommen, Sie haben ein
House
Objekt, das wiederum einKitchen
und einLivingRoom
Objekt enthält, und dasLivingRoom
Objekt enthält auch einTV
Objekt.Die einfachste Methode, um dies zu erreichen, besteht darin, dass jedes Objekt seine untergeordneten Elemente mit seiner Konstruktionsmethode erstellt. Wenn die Eigenschaften jedoch relativ verschachtelt sind, werden Sie beim
House
fehlgeschlagenen Erstellen wahrscheinlich einige Zeit damit verbringen, genau zu isolieren, was fehlschlägt.Die Alternative besteht darin, Folgendes zu tun (Abhängigkeitsinjektion, wenn Sie den ausgefallenen Begriff mögen):
Wenn der Prozess des Erstellens eines
House
fehlschlägt, gibt es nur einen Ort, an dem Sie suchen müssen. Es ist jedoch alles andere alsHouse
praktisch, diesen Block jedes Mal verwenden zu müssen, wenn Sie einen neuen wünschen . Betreten Sie die Fabriken:Dank der Factory hier wird der Prozess des Erstellens eines a
House
abstrahiert (da Sie nicht jede einzelne Abhängigkeit erstellen und einrichten müssen, wenn Sie nur ein erstellen möchtenHouse
) und gleichzeitig zentralisiert, was die Wartung erleichtert. Es gibt andere Gründe, warum die Verwendung separater Fabriken von Vorteil sein kann (z. B. Testbarkeit), aber ich finde diesen speziellen Anwendungsfall, um am besten zu veranschaulichen, wie nützlich Factory-Klassen sein können.quelle
HouseFactory
Klasse übergeben?create
Methode. Wenn SieHouse
beispielsweise immer die gleiche Art vonLivingRoom
haben, kann es sinnvoll sein, die Parameter in der Factory-Klasse fest zu codieren, anstatt sie als Argumente zu übergeben. Oder Sie möchtentype
IhrerHouseFactory::create
Methode ein Argument geben, wenn Sie einige Arten vonLivingRoom
s haben und einen Schalter mit den für jeden Typ fest codierten Parametern haben.Es ist wichtig, die Idee hinter der Verwendung der Fabrik oder der Fabrikmethode klar zu unterscheiden. Beide sollen sich gegenseitig ausschließende Probleme bei der Objekterstellung ausschließen.
Lassen Sie uns die "Fabrikmethode" genau beschreiben:
Wenn Sie eine Bibliothek oder APIs entwickeln, die wiederum für die weitere Anwendungsentwicklung verwendet werden, ist die Factory-Methode eine der besten Auswahlmöglichkeiten für das Erstellungsmuster. Grund dahinter; Wir wissen, dass, wann ein Objekt mit den erforderlichen Funktionen erstellt werden soll, der Objekttyp jedoch unentschlossen bleibt oder ob dynamische Parameter übergeben werden .
Nun ist der Punkt, dass ungefähr dasselbe erreicht werden kann, indem das Factory-Muster selbst verwendet wird, aber ein großer Nachteil wird in das System eingeführt, wenn das Factory-Muster für das oben hervorgehobene Problem verwendet wird. Es ist, dass Ihre Logik, verschiedene Objekte (Unterklassenobjekte) zu erstellen, dies tut Seien Sie in Zukunft spezifisch für bestimmte Geschäftsbedingungen, wenn Sie die Funktionalität Ihrer Bibliothek für andere Plattformen erweitern müssen (Technisch gesehen müssen Sie weitere Unterklassen der Basisschnittstelle oder der abstrakten Klasse hinzufügen, damit Factory diese Objekte zusätzlich zu den vorhandenen auch zurückgibt basierend auf einigen dynamischen Parametern) dann jedes Mal, wenn Sie die Logik der Factory-Klasse ändern (erweitern) müssen, was kostspielig und aus konstruktiver Sicht nicht gut ist. Auf der anderen Seite, wenn "Fabrikmethode"
quelle
Sie sind auch nützlich, wenn Sie mehrere "Konstruktoren" mit demselben Parametertyp, aber unterschiedlichem Verhalten benötigen.
quelle
Es ist eine gute Idee, Factory-Methoden innerhalb des Objekts zu verwenden, wenn:
Es ist eine gute Idee, eine abstrakte Factory- Klasse zu verwenden, wenn:
quelle
UML von
Produkt: Definiert eine Schnittstelle der Objekte, die die Factory-Methode erstellt.
ConcreteProduct: Implementiert die Produktschnittstelle
Ersteller: Deklariert die Factory-Methode
ConcreateCreator: Implementiert die Factory-Methode, um eine Instanz eines ConcreteProduct zurückzugeben
Problemstellung: Erstellen Sie eine Factory of Games mithilfe von Factory-Methoden, die die Spieloberfläche definieren.
Code-Auszug:
Ausgabe:
Dieses Beispiel zeigt eine
Factory
Klasse durch Implementierung von aFactoryMethod
.Game
ist die Schnittstelle für alle Arten von Spielen. Es definiert komplexe Methoden:createGame()
Chess, Ludo, Checkers
Es gibt verschiedene Varianten von Spielen, die eine Implementierung ermöglichencreateGame()
public Game getGame(String gameName)
istFactoryMethod
in derIGameFactory
KlasseGameFactory
Erstellt verschiedene Arten von Spielen im Konstruktor vor. Es implementiert dieIGameFactory
Factory-Methode.Der Spielname wird als Befehlszeilenargument an übergeben
NotStaticFactoryDemo
getGame
inGameFactory
akzeptiert einen Spielnamen und gibt das entsprechendeGame
Objekt zurück.Fabrik:
FactoryMethod
Anwendungsfall:
Wann zu verwenden:
Client
weiß nicht, welche konkreten Klassen zur Laufzeit erstellt werden müssen, sondern möchte nur eine Klasse erhalten, die den Job erledigt.quelle
getArea()
ist keine Factory - Methode überhaupt .Es ist wirklich Geschmackssache. Factory-Klassen können nach Bedarf abstrahiert / verbunden werden, während Factory-Methoden leichter sind (und auch testbar sind, da sie keinen definierten Typ haben, aber einen bekannten Registrierungspunkt erfordern, der einem Service ähnelt Locator, aber zum Auffinden von Werksmethoden).
quelle
Factory-Klassen sind nützlich, wenn der von ihnen zurückgegebene Objekttyp einen privaten Konstruktor hat, wenn verschiedene Factory-Klassen unterschiedliche Eigenschaften für das zurückgebende Objekt festlegen oder wenn ein bestimmter Factory-Typ mit seinem zurückkehrenden Betontyp gekoppelt ist.
WCF verwendet ServiceHostFactory-Klassen, um ServiceHost-Objekte in verschiedenen Situationen abzurufen. Die Standard-ServiceHostFactory wird von IIS zum Abrufen von ServiceHost-Instanzen für SVC- Dateien verwendet. Eine WebScriptServiceHostFactory wird jedoch für Dienste verwendet, die Serialisierungen an JavaScript-Clients zurückgeben. ADO.NET Data Services verfügt über eine eigene spezielle DataServiceHostFactory und ASP.NET über eine ApplicationServicesHostFactory, da die Dienste über private Konstruktoren verfügen.
Wenn Sie nur eine Klasse haben, die die Factory verbraucht, können Sie einfach eine Factory-Methode innerhalb dieser Klasse verwenden.
quelle
Stellen Sie sich ein Szenario vor, in dem Sie eine Auftrags- und Kundenklasse entwerfen müssen. Der Einfachheit halber und den anfänglichen Anforderungen zufolge benötigen Sie für die Auftragsklasse keine Fabrik und füllen Ihre Anwendung mit vielen 'new Order ()' - Anweisungen. Die Dinge funktionieren gut.
Nun kommt eine neue Anforderung ins Spiel, dass das Bestellobjekt ohne Kundenzuordnung nicht instanziiert werden kann (neue Abhängigkeit). Jetzt haben Sie folgende Überlegungen.
1- Sie erstellen eine Konstruktorüberladung, die nur für neue Implementierungen funktioniert. (Inakzeptabel). 2- Sie ändern die Order () - Signaturen und ändern jeden Aufruf. (Keine gute Übung und echte Schmerzen).
Stattdessen Wenn Sie eine Factory für die Auftragsklasse erstellt haben, müssen Sie nur eine Codezeile ändern, und schon kann es losgehen. Ich empfehle die Factory-Klasse für fast jede aggregierte Assoziation. Hoffentlich hilft das.
quelle
wenn Sie ein anderes Objekt in Bezug auf die Verwendung erstellen möchten. Es ist nützlich.
quelle
Jede Klasse, die die Objekterstellung für das Objekt, mit dem sie arbeiten muss, auf ihre Unterklasse verschiebt, kann als Beispiel für ein Factory-Muster angesehen werden.
Ich habe dies in einer anderen Antwort unter https://stackoverflow.com/a/49110001/504133 ausführlich erwähnt
quelle
Ich denke, es hängt vom losen Kopplungsgrad ab, den Sie in Ihren Code einbringen möchten.
Die Fabrikmethode entkoppelt die Dinge sehr gut, aber die Fabrikklasse Nr.
Mit anderen Worten, es ist einfacher, Dinge zu ändern, wenn Sie die Factory-Methode verwenden, als wenn Sie eine einfache Factory (als Factory-Klasse bezeichnet) verwenden.
Schauen Sie sich dieses Beispiel an: https://connected2know.com/programming/java-factory-pattern/ . Stellen Sie sich nun vor, Sie möchten ein neues Tier mitbringen. In der Factory-Klasse müssen Sie die Factory ändern, aber in der Factory-Methode müssen Sie nur eine neue Unterklasse hinzufügen.
quelle
Fabrikklassen sind schwerer, bieten aber gewisse Vorteile. In Fällen, in denen Sie Ihre Objekte aus mehreren Rohdatenquellen erstellen müssen, können Sie nur die Gebäudelogik (und möglicherweise die Aggregation der Daten) an einem Ort kapseln. Dort kann es abstrakt getestet werden, ohne sich um die Objektschnittstelle zu kümmern.
Ich habe festgestellt, dass dies ein nützliches Muster ist, insbesondere wenn ich ORM nicht ersetzen kann und unzureichend bin und viele Objekte aus DB-Tabellenverknüpfungen oder gespeicherten Prozeduren effizient instanziieren möchte.
quelle
Ich vergleiche Fabriken mit dem Konzept der Bibliotheken. Beispielsweise können Sie eine Bibliothek zum Arbeiten mit Zahlen und eine andere zum Arbeiten mit Formen haben. Sie können die Funktionen dieser Bibliotheken in logisch benannten Verzeichnissen als
Numbers
oder speichernShapes
. Dies sind generische Typen, die bei Formen Ganzzahlen, Gleitkommazahlen, Dobuli, Longs oder Rechtecke, Kreise, Dreiecke und Pentagone umfassen können.Der Factory Petter verwendet Polymorphismus, Abhängigkeitsinjektion und Inversion der Kontrolle.
Der angegebene Zweck der Fabrikmuster ist:
Define an interface for creating an object, but let subclasses decide which class to instantiate. Factory Method lets a class defer instantiation to subclasses.
Nehmen wir also an, Sie erstellen ein Betriebssystem oder Framework und alle diskreten Komponenten.
Hier ist ein einfaches Beispiel für das Konzept des Factory-Musters in PHP. Ich bin vielleicht nicht zu 100% damit einverstanden, aber es soll als einfaches Beispiel dienen. Ich bin kein Experte.
quelle
NumbersFactory::makeNumber( 'float', 12.5 );
es mir zu sagen,new Float(12.5);
wenn ich weiß, dass ich eine braucheFloat
? Das verstehe ich nicht über Fabriken ... worum geht es?