One of the ways to implement Dependency Injection correctly is to separate object creation from business logic. Typically, this involves using a Factory for object creation.
Up until this point, I’ve never seriously considered using a Factory so I apologize if this question seems a little simplistic:
In all the examples of the Factory Pattern that I’ve run across, I always see very simple examples that have no parameterization. For example, here’s a Factory stolen from Misko Hevery’s excellent How To Think About the "new" Operator article.
class ApplicationBuilder { House build() { return new House(new Kitchen( new Sink(), new Dishwasher(), new Refrigerator()) ); } }
However, what happens if I want each house that I build to have a name? Am I still using the Factory pattern if I re-write this code as follows?
class ApplicationBuilder { House build( const std::string & house_name) { return new House( house_name, new Kitchen(new Sink(), new Dishwasher(), new Refrigerator()) ); } }
Note that my Factory method call has changed from this:
ApplicationBuilder builder; House * my_house = builder.build();
To this:
ApplicationBuilder builder; House * my_house = builder.build('Michaels-Treehouse');
By the way: I think the concept of separating object instantiation from business logic is great, I’m just trying to figure out how I can apply it to my own situation. What confuses me is that all the examples I’ve seen of the Factory pattern never pass any parameters into the build() function.
To be clear: I don’t know the name of the house until the moment before I need to instantiate it.
I’ve seen quite a lot of examples that use a fixed set of arguments, like in your name example, and have used them myself too and i can’t see anything wrong with it.
However there is a good reason that many tutorials or small articles avoid showing factories that forward parameters to the constructed objects: It is practically impossible to forward arbitrary number of arguments (even for a sane limit like 6 arguments). Each parameter you forward has to be accepted as
const T&andT&if you want to do it generic.For more complicated examples, however, you need an exponentially growing set of overloads (for each parameter, a const and a nonconst version) and perfect forwarding is not possible at all (so that temporaries are forwarded as temporaries, for example). For the next C++ Standard that issue is solved:
That way, you can call
And it will return
Read the article i linked above.