Jump to content
  • Advertisement
Sign in to follow this  
crancran

Factory self registration

This topic is 2479 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I am struggling with a good approach on how to handle object registration with a factory class. Lets take the following several classes:


class BaseObject {
public:
BaseObject(int id) { }
virtual ~BaseObject() { }
};

class DerivedObject1 : public BaseObject {
public:
DerviedObject1(int id) : BaseObject(id) { }
virtual ~DerivedObject1() { }
};

class DerivedObject2 : public BaseObject {
public:
DerivedObject2(int id) : BaseObject(id) { }
virtual ~DerivedObject2() { }
};


class ObjectFactory {
/* ... */
void registerObject(std::string& objectType, pointer to create method);
}


class DerivedObject2Manager {
public:
DerivedObject2* createObject(...) { }
};


If we ignore the factory/registration concept for the moment, the DerivedObject2Manager (they're not called managers in my case, just using term as example) is responsible for the life-cycle of the instances of the DerivedObject2 classes it creates via the createObject() method. The problem is there is another class that parses an XML file and it needs to have a factory registration map that indicates for this object DerivedObject2 you need to invoke the createObject method in class DerivedObject2Manager.

How can I accomplish this via using templates/defines or static member variables to populate an object factory at program start-up so that I do not have to remember to change initialization functions but rather control it in the .H/.CPP of the derived objects. This way as I add more classes, it's an automatic thing.

Share this post


Link to post
Share on other sites
Advertisement
It seems like you are asking your factory class to be able to call any method in the manager class you tell it to regardless of parameters. So for instance DerivedObject2Manager might have createObject as follows:

DerivedObject2* createObject(bool initialize, int type);

but DerivedObject1Manager might have

DerivedObject1* createObject(int initialValue, int type);

If this is the case, I think this will be extremely difficult if not impossible. You need a common interface in order for the factory class to work. Instead, you need to define something like




class BaseObject {
public:
BaseObject(int id) { }
virtual ~BaseObject() { }
};

class BaseManager
{
public:
virtual BaseObject* createObject(int id) = 0;
};

class DerivedObject1 : public BaseObject {
public:
DerviedObject1(int id) : BaseObject(id) { }
virtual ~DerivedObject1() { }
};

class DerivedObject2 : public BaseObject {
public:
DerivedObject2(int id) : BaseObject(id) { }
virtual ~DerivedObject2() { }
};

class ObjectFactory {
void registerObject(std::string& objectType, BaseManager* manager);
}

class DerivedObject2Manager : BaseManager {
public:
BaseObject* createObject(int id) { }
};




In order for you to automatically register it, you could have a global variable that is an instance of an ObjectFactory and have each derived manager register itself as part of its constructor. I hope that answers your question.

Share this post


Link to post
Share on other sites

It seems like you are asking your factory class to be able to call any method in the manager class you tell it to regardless of parameters. So for instance DerivedObject2Manager might have createObject as follows:

DerivedObject2* createObject(bool initialize, int type);

but DerivedObject1Manager might have

DerivedObject1* createObject(int initialValue, int type);

If this is the case, I think this will be extremely difficult if not impossible. You need a common interface in order for the factory class to work. Instead, you need to define something like




class BaseObject {
public:
BaseObject(int id) { }
virtual ~BaseObject() { }
};

class BaseManager
{
public:
virtual BaseObject* createObject(int id) = 0;
};

class DerivedObject1 : public BaseObject {
public:
DerviedObject1(int id) : BaseObject(id) { }
virtual ~DerivedObject1() { }
};

class DerivedObject2 : public BaseObject {
public:
DerivedObject2(int id) : BaseObject(id) { }
virtual ~DerivedObject2() { }
};

class ObjectFactory {
void registerObject(std::string& objectType, BaseManager* manager);
}

class DerivedObject2Manager : BaseManager {
public:
BaseObject* createObject(int id) { }
};




In order for you to automatically register it, you could have a global variable that is an instance of an ObjectFactory and have each derived manager register itself as part of its constructor. I hope that answers your question.


Why don't you use dependency injection to register these factories? Change your factories' constructors to accept some interface with a method to register the factory. The constructor will register itself.

Share this post


Link to post
Share on other sites

Why don't you use dependency injection to register these factories? Change your factories' constructors to accept some interface with a method to register the factory. The constructor will register itself.


Can you illustrate this approach with an example?

Share this post


Link to post
Share on other sites

It seems like you are asking your factory class to be able to call any method in the manager class you tell it to regardless of parameters. So for instance DerivedObject2Manager might have createObject as follows:

DerivedObject2* createObject(bool initialize, int type);

but DerivedObject1Manager might have

DerivedObject1* createObject(int initialValue, int type);

If this is the case, I think this will be extremely difficult if not impossible. You need a common interface in order for the factory class to work. Instead, you need to define something like


Yes, all manager classes would have the same signature for the createObject() method.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!