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& and T& 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:
class ApplicationBuilder {
template<typename... T>
House *build( T&&... t ) {
return new House( std::forward<T>(t)...,
new Kitchen(new Sink(),
new Dishwasher(),
new Refrigerator())
);
}
};
That way, you can call
builder.build("Hello", 13);
And it will return
new House("Hello", 13, new Kitchen(new Sink(...
Read the article i linked above.
Not only is is acceptable, but it's common to pass parameters to a factory method. Check out some examples. Normally the parameter is a type telling the factory what to make, but there's no reason you can't add other information you need to build an object. I think what you're doing is fine.
I can't see why it would be wrong to add this parameter to your factory. But be aware that you shouldn't end up adding many parameters which might not be useful to all objects created by the factory. If you do, you'll have lost quite a lot of the advantages of a factory !
The idea of a factory is that it gives you an instance of a class/interface, so there is nothing wrong with passing parameters. If there were, it would be bad to pass parameters to a new() as well.
I agree with Benoit. Think of a factory for creating something like sql connections though, in a case like this it would be necessary to pass information about the connection to the factory. The factory will use that information to use the correct server protocol and so on.
Sure, why not..!?
The nice thing about passing parameters is that it allows you to hide the implementation of the concrete object. For example, in the code you posted you pass the parameters to the constructor. However, you may change the implementation so that they get passed via an Initiailze method. By passing parameters to the factory method you hide the nature of constructing and initializing the object from the caller.
Take a look at Loki::Factory, there's an implementation very much like it coming to Boost as well, however. Some example code i regularly use in different flavors:
typedef Loki::SingletonHolder< Loki::Factory< Component, std::string, Loki::Typelist< const DataCollection&, Loki::Typelist< Game*, Loki::NullType > > > > ComponentFactory;
This might seem a bit weird at first sight, however let me explain this beast and how powerful it really is. Basically we create a singleton which holds a factory, the out most parameters are for the singleton, Component is our product, std::string is our creation id type, after this follows a type list of the params which is required for creation of Components ( this can be defined using a macro as well for a less verbose syntax ). After this line one can just do:
ComponentFactory::Instance().CreateObject( "someStringAssociatedWithConcreteType", anDataCollection, aGamePointer );
To create objects, to register one just use ComponentFactory::Instance().Register();. There's a great chapter on the details in the book Modern C++ Design.
Related
My team works on an HTTP web server in C++. The codebase has aged over time, and has a widespread problem of 12+ parameters being passed to every function.
A fake example: We need to build a Car, but in order to do that, we have the following function:
MaybeBuildCar(engine_params, steering_params, interior_params, fuel_params, available_inventory, parts, &debug);
Someone on our team has proposed that we create a wrapper CarBuilder class whose constructor takes in the params and "stateful" objects like available_inventory, then has a separate function for BuildCar as follows:
CarBuilder car_builder(engine_params, steering_params, interior_params, fuel_params, available_inventory, &debug);
auto car = car_builder.BuildCar(parts);
Personally, I don't see much value in having a class with a single public function that is always called. We'll always need these parameters, and we'll always need the parts, so this just adds more steps to build the car. It could even add confusion, as now a user of CarBuilder must know to both construct it and call BuildCar.
Admittedly, this simplifies our helper functions within car_builder.cc, as they also require passing these params, but to me that's misusing what a class is for: maintaining state.
Is creating this CarBuilder a misuse of the class, or is simply cleaning up function signatures a valid use? Does anyone have any suggestions on how to tackle this problem?
Minimizing function parameters can be a blessing for heavily used functions in a performance-sensitive environment:
If you pass 6 references to a function, that is 6 pointer copies pushed to the stack;
If you pass a single CarBuilder, it is one "reference-that-contains-6-other-references".
It depends on your situation.
you could define a class that contains all parameters and in each function just passed this object.
struct CarComponent
{
public:
EngineParams engine_params;
SteeringParams steering_params;
InteriorParams interior_params;
FuelParams fuel_params;
AvailableInventory available_inventory
};
MaybeBuildCar(car_component);
other_function(car_component);
Advantage:
Function's signature is decoupled from changing members of the struct (CarComponent). easy to change.
Refactor all the parameters in each function with a specific object. it prevents repetition and it becomes easier to read the code.
Edit: TL;DR
I guess my main problem is I don't know how to store a list of functions that all take one argument, where the argument type is different between each function, but always extends from EventBase, for calling later.
i.e: EventChild extends from EventBase. A function with the signature
<void (EventChild&)>
will not fit into a variable of type
std::function<void(EventBase&)>
How do I store functions like this, knowing that a user shouldn't have to modify the class where they are stored each time they create a new event extending from our EventBase class?
Note: I had previously been told I could use a dynamic_cast to accomplish this. I have been trying to do exactly that, but it hasn't been working. I imagine for that to work I would have to use pointers somehow, but I am new enough to C++ that I'm not sure how to do it. Maybe that should be the starting point?
One of the problems with dynamic casting pointers I have been having is 'I can convert a pointer of type:
(Subbscriber*)(getDemoEvent(EventDemo&)
to type:
void(EventBase&)
or something along those lines. (not at my computer right now to try it)
This is obviously a problem limited to member functions, I assume.
I recently posted a question on here with the intention of solving an issue for a C++ Event system based on a "Publisher->Dispatcher->Subscriber" pattern. I don't know the exact name of this pattern, but I hear that it is a variant on the Observer pattern with an added "middle-man."
I have been trying to get this system to work for a while now and I am completely stuck. It was suggested in the comments of the previous question that for what I was trying to accomplish, my program layout is incorrect. This is very likely the case since I had been researching other event systems that were close to what I am after trying to modify them for use they were unintended for. So I figured I would describe what I am after, and ask the more general question of "How would you go about structuring and creating this?"
So here is my general idea of how the system should be laid out and how it should operate in a basic example:
Starting with the idea of 5 different files (plus headers and maybe some subclasses):
main.cpp
dispatcher.cpp
publisher.cpp
subscriber.cpp
eventbase.cpp
publishers and subscribers could be anything, and they only serve as an example here.
The first order of business would be to create an instance of our Dispatcher class.
Following that, we create instances of our publisher/subscriber classes. These 2 classes could be a part of the same file, different files, multiples of each, or not event be classes at all but simply free functions. For the sake of simplicity and testing, they are 2 separate classes that know nothing about each other.
When these 2 classes are created, they should be passed a reference or pointer to our dispatcher instance.
This is easy enough. Now let's get to how you should use the system.
A user of the system should be able to create a class that inherits from our EventBase class. Ideally, there should be no requirement on variables or functions to override from the base class.
Let's say we have created a new event class called EventDemo, with a public const char* demoString = "I am a Demo Event";.
From our subscriber class, we should be able to tell our dispatcher that we want to listen for and receive some events. The syntax for doing so should be as simple as possible.
Lets create a member function in our subscriber that looks like this:
void Subscriber::getDemoEvent(const EventDemo &ev) {
std::cout << ev.demoString;
}
Now we need a way to bind that member function to our dispatcher. We should probably do that in our constructor. Let's say that the reference to our dispatcher that we passed to our subscriber when we created it is just called 'dispatcher'.
The syntax for subscribing to an event should look something like this:
dispatcher->subscribe("EventToSubTo", &getDemoEvent);
Now since we are in a class trying to pass a member function, this probably isn't possible, but it would work for free functions.
For member functions we will probably need and override that looks like this:
dispatcher->subscribe("EventToSubTo", &Subscriber::getDemoEvent, this);
We use 'this' since we are inside the subscribers constructor. Otherwise, we could use a reference to our subscriber.
Notice that I am simply using a string (or const char* in c++ terms) as my "Event Key". This is on purpose, so that you could use the same event "type" for multiple events. I.E: EventDemo() can be sent to keys "Event1" and "Event2".
Now we need to send an event. This can be done anywhere we have a reference to our dispatcher. In this case, somewhere in our publisher class.
The syntax should look something like this to send our EventDemo:
dispatcher->emit("EventToSubTo", EventDemo());
Super simple. It's worth noting that we should be able to assign data to our event through it's constructor, or even template the event. Both of these cases are only valid if the event created by the user supports it.
In this case, the above code would look something like this:
dispatcher->emit("EventToSubTo", EventDemo(42));
or
dispatcher->emit("EventToSubTo", EventDemo<float>(3.14159f));
It would be up to the user to create a member function to retrieve the data.
OK, so, all of that should seem pretty simple, and in fact, it is, except for one small gotcha. There are already systems out there that store functions in a map with a type of .
And therein lies the problem...
We can store our listener functions, as long as they accept a type of EventBase as their argument. We would then have to type cast that argument to the type of event we are after. That's not overly difficult to do, but that's not really the point. The point is can it be better.
Another solution that was brought up before was the idea of having a separate map, or vector, for each type of event. That's not bad either, but would require the user to either modify the dispatcher class (which would be hard to do when this is a library), or somehow tell the dispatcher to "create this set of maps" at compile time. That would also make event templating a nightmare.
So, the overly generalized question: How do we do that?
That was probably a very long winded explanation for something seemingly simple, but maybe someone will come along not not know about it.
I am very interested to hear thoughts on this. The core idea is that I don't want the 2 communicators (publisher and subscriber) to have to know anything about each other (no pointers or references), but still be able to pass arbitrary data from one to the other. Most implementations I have seen (signals and slots) require that there be some reference to each other. Creating a "middle-man" interface feels much more flexible.
Thank you for your time.
For reference to my last question with code examples of what I have so far:
Store a function with arbitrary arguments and placeholders in a class and call it later
I have more samples I could post, but I think it's highly likely that the structure of the system will have to change. Waiting to hear thoughts!
Background:
I have a Framework where I work on Objects. Up till now I created Objects in the framework with a default constructor. Now I want to introduce some customization on creation of the Objects. I decided it would be nice to allow to pass a factory into the Framework. I call it Provider, I will explain why below.
The only thing I expect in the Framework is to have a thing that will behave something like this
template< typename Provider >
void Framework::make_objects( Provider obj_provider)
{
Object obj = obj_provider();
}
I would like Provider to be anything that is callable, and returns an Object to be passed. E.g:
Factory factory;
framework.make_objects( factory.make_object ); // [1] a Factory method
framework.make_objects( []() { return Object(); } ); // [2] lambda
framework.make_objects( function_that_spits_Object ); // [3] a simple function
I call Provider a provider, and not a factory, because it is more of just a method of a factory.
Problem:
I cannot figure out a way with a simple front-end interface to pass and possibly store any kind of callable object (with a given signature). Is it possible?
What I tried:
I tried std::function, and got it to work, but gets really ugly when I want to provide Objects using a Factory method because it is overloaded, and a member method. So I need to bind factory instance to an overloaded member method. Possible but really ugly from the user side.
I think a template similar to the one Background example, would work, but it would be extremely nice to be able to store and pass the Provider. And I couldn't figure out how the template should be written to allow that.
I know that I can resolve my background/original problem, I could accept a whole Factory in the Framework, and write a constructor that would accept std::function and wrap it, so the function-type providers would implicitly get converted to Factory.
However my question for here is, is this possible to implement, to accept and store any kind of callable object, so I can just use provider() any where in the framework whenever I need a new object. This is the technical issue I am interested in here.
You can just put the member call inside the lambda, e.g. [factory] { return factory.make_object(); }. std::function is the solution here.
The problem that binding member functions sucks has nothing to do with what you're going to do with the result- there's no class or type you can use that can solve the problem of producing a wrappable function object in the first place. The syntax of f(factory.make_object) is impossible to support for any type.
Just use a lambda to wrap the member function and use std::function.
I have a class that needs 12 parameters to be passed to its constructor. So I think that there is something wrong with the design of this class.
I would like to ask if there is any design pattern or a general collection of rules regarding the design of a class, especially its constructor.
12 parameters definitely sound too many to me. Options to reduce their numbers are:
Introduce Parameter Object by grouping logically related parameters into an object and passing that object instead of the individual parameters.
Introduce a Builder (optionally with method chaining). This does not reduce the actual parameter list but it makes the code more readable, and is especially useful if you have several different creation scenarios with varying parameters. So instead of
MyClass someObject = new MyClass(aFoo, aBar, aBlah, aBaz, aBorp, aFlirp,
andAGoo);
MyClass anotherObject = new MyClass(aFoo, null, null, aBaz, null, null,
andAGoo);
you can have
MyClass someObject = new MyClassBuilder().withFoo(aFoo).withBar(aBar)
.withBlah(aBlah).withBaz(aBaz).withBorp(aBorp).withFlirp(aFlirp)
.withGoo(aGoo).build();
MyClass anotherObject = new MyClassBuilder().withFoo(aFoo).withBaz(aBaz)
.withGoo(aGoo).build();
(Maybe I should have started with this ;-) Analyse the parameters - Are all of them really needed in the constructor (i.e. mandatory)? If a parameter is optional, you may set it via its regular setter instead of the constructor.
If your function takes eleven parameters, you probably have forgotten one more
I love this sentence because it sums it all: Bad design calls for bad design.
I took this is from the book C++ Coding Standards: 101 Rules, Guidelines, And Best Practices by Herb Sutter, Andrei Alexandrescu.
Edit: The direct quote is If you have a procedure with ten parameters, you probably missed some. It is itself a quote from Alan Perlis.
Functions with so many parameters are a symtom of bad design.
One of the possibility is to try to encapsulate part of these parameters in an entity/class that has a defined goal. (not a garbage class that would list all parameters without meaningful structure).
Never forget the Single Responsibility Principle
As a consequence, classes remain limited in size, and as a consequence, limited in number of member paramters, and thus limited in the size of parameters needed for its constructors. Like one of the comments below says, the class with so much constructor parameters may handle too much futile details independent of its main goal.
A look at this one is advised too: How many parameters are too many?
12 Parameters, something is most probably wrong with the design.
What is done with the parameters?
Does the class just send them into other constructors? Then perhaps it should just accept interfaces to ready constructed objects.
Is the class large and does a lot of things with all these parameters? Then the class has to much responsibility and should accept classes that takes care of the details instead.
Are there any "clusters" in the parameters? Perhaps are some of the parameters a class in the creation. Encapsulate them and give them the appropriate responsibility.
The alternative is that this is parameters for a lowlevel, performance critical construction, in which case the design just have to take back seat, but that is rarely the case.
if it is possible you may group the parameters by classes and pass their instances to the constructor.
I think this can be acceptable when using the State pattern for example. However, might I suggest passing the object (if appropriate) that those parameters come from instead? And then in the constructor loading the data from it?
I am developing a C++ application used to simulate a real world scenario. Based on this simulation our team is going to develop, test and evaluate different algorithms working within such a real world scenrio.
We need the possibility to define several scenarios (they might differ in a few parameters, but a future scenario might also require creating objects of new classes) and the possibility to maintain a set of algorithms (which is, again, a set of parameters but also the definition which classes are to be created). Parameters are passed to the classes in the constructor.
I am wondering which is the best way to manage all the scenario and algorithm configurations. It should be easily possible to have one developer work on one scenario with "his" algorithm and another developer working on another scenario with "his" different algorithm. Still, the parameter sets might be huge and should be "sharable" (if I defined a set of parameters for a certain algorithm in Scenario A, it should be possible to use the algorithm in Scenario B without copy&paste).
It seems like there are two main ways to accomplish my task:
Define a configuration file format that can handle my requirements. This format might be XML based or custom. As there is no C#-like reflection in C++, it seems like I have to update the config-file parser each time a new algorithm class is added to project (in order to convert a string like "MyClass" into a new instance of MyClass). I could create a name for every setup and pass this name as command line argument.
The pros are: no compilation required to change a parameter and re-run, I can easily store the whole config file with the simulation results
contra: seems like a lot of effort, especially hard because I am using a lot of template classes that have to be instantiated with given template arguments. No IDE support for writing the file (at least without creating a whole XSD which I would have to update everytime a parameter/class is added)
Wire everything up in C++ code. I am not completely sure how I would do this to separate all the different creation logic but still be able to reuse parameters across scenarios. I think I'd also try to give every setup a (string) name and use this name to select the setup via command line arg.
pro: type safety, IDE support, no parser needed
con: how can I easily store the setup with the results (maybe some serialization?)?, needs compilation after every parameter change
Now here are my questions:
- What is your opinion? Did I miss
important pros/cons?
- did I miss a third option?
- Is there a simple way to implement the config file approach that gives
me enough flexibility?
- How would you organize all the factory code in the seconde approach? Are there any good C++ examples for something like this out there?
Thanks a lot!
There is a way to do this without templates or reflection.
First, you make sure that all the classes you want to create from the configuration file have a common base class. Let's call this MyBaseClass and assume that MyClass1, MyClass2 and MyClass3 all inherit from it.
Second, you implement a factory function for each of MyClass1, MyClass2 and MyClass3. The signatures of all these factory functions must be identical. An example factory function is as follows.
MyBaseClass * create_MyClass1(Configuration & cfg)
{
// Retrieve config variables and pass as parameters
// to the constructor
int age = cfg->lookupInt("age");
std::string address = cfg->lookupString("address");
return new MyClass1(age, address);
}
Third, you register all the factory functions in a map.
typedef MyBaseClass* (*FactoryFunc)(Configuration *);
std::map<std::string, FactoryFunc> nameToFactoryFunc;
nameToFactoryFunc["MyClass1"] = &create_MyClass1;
nameToFactoryFunc["MyClass2"] = &create_MyClass2;
nameToFactoryFunc["MyClass3"] = &create_MyClass3;
Finally, you parse the configuration file and iterate over it to find all the entries that specify the name of a class. When you find such an entry, you look up its factory function in the nameToFactoryFunc table and invoke the function to create the corresponding object.
If you don't use XML, it's possible that boost::spirit could short-circuit at least some of the problems you are facing. Here's a simple example of how config data could be parsed directly into a class instance.
I found this website with a nice template supporting factory which I think will be used in my code.