I need to construct two objects, A and B. These A and B objects can be initialized in different ways.
Design pattern to construct A (working):
A has subclasses A_txt, A_tsv, A_csv, etc. Each A subtype is constructed from a string (a file path), but each one loads the file in a different way. I’ve built a registry that maps the file type (e.g. txt) to the appropriate factory for creating that object:
txt –> A_txt_Factory
tsv –> A_tsv_Factory
…
Where A_txt_factory receives a file path, loads it as a text file, and then returns a pointer to an A_txt object.
Together, I use this registry as a factory: given a file path and a file type, it looks up the factory corresponding to that tag and uses it to construct and returns a pointer to an A object.
I really like this combination registry and factory design pattern; someone else can easily make their own file type and a factory for loading it, check it into the registry, and use it without looking at the other code.
Design pattern to construct B (I need help):
Constructing B objects is more difficult, because they don’t all load from the same type (e.g. all A subtypes are constructed with a string indicating the file path). B_text will load from a text file (from a provided string indicating the file path), but unlike before B_intAndA may initialize from an int and an instance of A.
What design pattern can I use to create B? As before, I will have a string tag to indicate which factory will be used; however, unlike before, each factory will accept different parameters (and possibly a different number of parameters). I suppose that could be accomplished somehow with a variadic template function of variadic parameters (I’m using C++11, so that is an option).
Does this design pattern ever come up for anyone else (same base class, but constructed with different numbers of arguments with different types)?
It’s easy to make individual factories that construct the different B subtypes, but difficult to know how to allow them to be indexed with a registry since they accept different types and numbers of parameters.
How would you handle this?
At some time point T1 the kind of B to be created, is known. The kind of B implies the signature of the constructor. At some time point T2, which might be the same or later, the B is created.
If the argument values are known at point T1, then if T2 = T1 just create the B here and problem solved. Otherwise if T2 > T1, store the arguments and the creation call in a functor (e.g.
[=]() -> B* { return new B_int_and_A( 42, *anAPointer ); }) and pass that, e.g. as astd::function, to T2.Otherwise, if argument values are not known at point T1 then you must have T2 > T1, and the argument values – regardless of kind of B – must be known at T2. In this case pass a B kind id forward to T2. Then at point T2 look up the arguments and creation function from the id, for example in a
switch.I don’t see how this has anything to do with C++, though.
What’s the connection?