Frage

Eine der Möglichkeiten, Dependency Injection korrekt zu implementieren, ist zu Objekterstellung von Geschäftslogik zu trennen. Typischerweise beinhaltet dies eine Fabrik für Objekterstellung verwendet wird.

Bis zu diesem Punkt habe ich noch nie ernsthaft eine Fabrik als mit so entschuldige ich mich, wenn diese Frage scheint ein wenig simpel:

In allen Beispielen der Fabrik-Muster, die ich laufe über habe, sehe ich immer sehr einfache Beispiele, die keine Parametrisierung haben. Zum Beispiel, hier ist ein Werk von Misko Hevery des ausgezeichnet Über das denken an "neuen" Operator Artikel.

class ApplicationBuilder {
  House build() {
    return new House(new Kitchen(
               new Sink(),
               new Dishwasher(),
               new Refrigerator())
           );
  }
}

Doch was passiert, wenn ich jedes Haus wollen, dass ich bauen einen Namen haben? Bin ich immer noch das Fabrikmuster verwenden, wenn ich diesen Code neu schreiben wie folgt?

class ApplicationBuilder {
  House build( const std::string & house_name) {
    return new House( house_name,
                      new Kitchen(new Sink(),
                                  new Dishwasher(),
                                  new Refrigerator())
                    );
  }
}

Beachten Sie, dass meine Fabrik Methodenaufruf wird von dieser geändert:

ApplicationBuilder builder;
House * my_house = builder.build();

Um dies zu:

ApplicationBuilder builder;
House * my_house = builder.build("Michaels-Treehouse");

übrigens: Ich denke, das Konzept Objekt Instanziieren von Business-Logik der Trennung ist groß, ich bin einfach nur, um herauszufinden, wie ich es auf meine eigene Situation anwenden kann. Was ich verwirrt ist, dass alle Beispiele, die ich von der Fabrik Mustern nie irgendwelche Parameter in die Build () Funktion übergeben gesehen haben.

Um klar zu sein: Ich weiß nicht, den Namen des Hauses bis zu dem Moment, bevor ich es zu instanziiert brauche

.
War es hilfreich?

Lösung

Ich habe eine ganze Reihe von Beispielen zu sehen, die einen festen Satz von Argumenten verwenden, wie in Ihrem Namen Beispiel, und habe sie selbst auch verwendet, und ich kann nichts daran zu beanstanden.

Allerdings gibt es einen guten Grund, dass viele Tutorials oder kleine Gegenstände Fabriken vermeiden zeigen, die Parameter auf die konstruierten Objekte weiter: Es ist praktisch unmöglich beliebige Anzahl von Argumenten zu übermitteln (auch für eine vernünftige Grenze wie 6 Argumente). Jeder Parameter Sie nach vorne muss als const T& und T& akzeptiert, wenn Sie es generic tun wollen.

Für kompliziertere Beispiele jedoch benötigen Sie eine exponentiell wachsende Menge von Überlastungen (für jeden Parameter, ein konstantes und einer nonconst Version) und perfektes Forwarding ist überhaupt nicht möglich ist (so dass Provisorien weitergeleitet werden als Provisorien, zum Beispiel). Für den nächsten C ++ Standard ist, Problem gelöst:

class ApplicationBuilder {
  template<typename... T>
  House *build( T&&... t ) {
    return new House( std::forward<T>(t)...,
                      new Kitchen(new Sink(),
                                  new Dishwasher(),
                                  new Refrigerator())
                    );
  }
};

Auf diese Weise können Sie anrufen

builder.build("Hello", 13);

Und es wird wieder

new House("Hello", 13, new Kitchen(new Sink(...

Lesen Sie den Artikel i oben verbunden.

Andere Tipps

Ich kann nicht sehen, warum es falsch wäre, diesen Parameter zu Ihrem Werk hinzuzufügen. Aber beachten Sie, dass Sie nicht viele Parameter angeben sollten am Ende, die von der Fabrik geschaffen, um alle Objekte möglicherweise nicht nützlich sein. Wenn Sie das tun, haben Sie verloren eine ganze Menge von den Vorteilen einer Fabrik!

Es ist nicht nur akzeptabel ist, aber es ist gemeinsam Parameter an eine Factory-Methode zu übergeben. Schauen Sie sich einige Beispiele . Normalerweise ist der Parameter eine Art die Fabrik zu sagen, was zu machen, aber es gibt keinen Grund, warum Sie nicht andere Informationen, die Sie ein Objekt bauen müssen hinzufügen können. Ich denke, was Sie tun, ist in Ordnung.

Die Idee einer Fabrik ist, dass es eine Instanz einer Klasse / Schnittstelle gibt, so gibt es nichts falsch mit Übergabe von Parametern. Gäbe es, wäre es schlecht Parameter zu übergeben, um einen neuen () als auch.

Ich stimme mit Benoit. Denken Sie an eine Fabrik für obwohl so etwas wie SQL-Verbindungen zu schaffen, in einem Fall wie diesem wäre es notwendig, Informationen über die Verbindung in die Fabrik zu übergeben. Die Fabrik wird diese Informationen verwendet, das richtige Server-Protokoll zu verwenden und so weiter.

Klar, warum nicht ..!?

Die nette Sache Parameter über vorbei ist, dass es die Umsetzung des konkreten Objekts verstecken kann. Zum Beispiel in dem Code geschrieben Sie die Parameter an den Konstruktor übergeben. Sie können jedoch die Implementierung ändern, so dass sie über eine übergeben bekommen Initiailze Methode. Durch die Parameter in die Fabrik-Methode übergeben verstecken Sie die Art der Konstruktion und der Initialisierung des Objekts von dem Anrufer.

Werfen Sie einen Blick auf Loki :: Fabrik, gibt es eine Implementierung sehr ähnlich wie es auch kommen Boost, aber. Einige Beispiel-Code i regelmäßig in verschiedenen Geschmacksrichtungen verwenden:

typedef Loki :: SingletonHolder >>> Component;

Dies könnte ein wenig seltsam auf den ersten Blick scheinen, mir dieses Tier aber lassen erklären und wie stark sie wirklich ist. Im Grunde wir einen Singleton schaffen, die eine Fabrik hält, die aus den meisten Parameter für die Singletons sind, ist Bestandteil unseres Produkt, std :: string ist unsere Schöpfung ID-Typ, nachdem diese eine Art Liste der params folgt, die für die Erstellung von Komponenten erforderlich ist (dies kann mit einem Makro als auch für eine weniger ausführliche Syntax definiert werden). Nach dieser Linie kann man nur tun:

Component :: Instanz () Create ( "someStringAssociatedWithConcreteType", anDataCollection, aGamePointer);.

Objekte zu erstellen, eine nur Component :: Instanz (). Register () verwenden, um zu registrieren, ;. Es gibt ein großes Kapitel über die Details in dem Buch Moderne C ++ Entwurf.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top