CXJ
CXJ

Reputation: 4459

How to specify concrete classes in factory for deferred instantiation / how to defer constructor call

I have a several server programs which have a bunch of common code, but differ in a few child class implementations. I use the abstract factory-like pattern something like this:

int main(int argc, char **argv) {
    Factory *factory = new Program1Factory();
    ServerThread theServer(factory);       // inject the dependencies
    theServer.start();
}

Factory is a pure abstract class, composed of the various bits I need to obtain the methods which have to vary from program to program. It looks roughly like this:

class Factory {
    public: virtual foo *getFooThing() = 0;
    public: virtual bar *getBarThing() = 0;
};

The concrete declaration and implementation for one program might look like this:

class Program1Factory : public Factory {
    public: virtual foo *getFooThing() { return new Program1Foo(); }
    public: virtual bar *getBarThing() { return new Program1Bar(); }
};

This worked fine until I got to a bunch of methods which themselves are child classes of a library over which I have no control.

In that library, the constructors of each of the classes require the data to be processed to be provided in the constructor! But my program does not yet have the data; it's just starting up and declaring its factory. Only once all the methods are set up and the threads start, do my server programs receive transactions which are the input to the constructors.

That is to say, in the example above, I cannot simply say:

return new Program1Bar()

because the class from which Program1Bar is derived only has a constructor that looks like

Program1Bar(string *inputString, string *outputString)

I don't have those values at the time my factory is instantiated.

I need to somehow create a pointer to the concrete class I want, store that pointer in my factory, and -- the hard part I cannot figure out -- instantiate (call the constructor) for those classes when data finally arrives.

How can I go about this?

Upvotes: 0

Views: 150

Answers (1)

Sodved
Sodved

Reputation: 8588

With those restrictions your Program1Bar class cannot be a subclass of the 3rd party library. Hard to talk abstract, but one suggestion would be for you to define a class like Task1Bar which is a subclass of your 3rd party library.

Then somewhere inside ProgramBar1::someMethod you can make your call to new Task1Bar. If you need the 3rd party library to persist across methods you can always define a member Task1Bar* task1 inside your Program1Bar class.

Just a suggestion, As I said, hard to define in the abstract.

Upvotes: 1

Related Questions