Hi, I am using an abstract factory to create user interface components such as dialogs. The abstract factory used is returned from a currently selected generic "INode" which is the base class for several different types of node. So for instance, if I want to add a new node of the same type as the selected node, the scenario goes something like this:
(please note this is semi-pseudo code)
User clicks node and the node gets stored for later use:
void onTreeNodeSelected(INode *node)
{
selectedNode = node;
}
User clicks "add" on the user interface:
void onAddClicked()
{
IFactory *factory = selectedNode->getFactory();
Dialog *dialog = factory->createAddDialog(parentWidget);
dialog->show();
}
Which all seems fine. The problem comes when I want to edit the selected node:
void onEditClicked()
{
IFactory *factory = selectedNode->getFactory();
Dialog *dialog = factory->createEditDialog(selectedNode, parentWidget);
dialog->show();
}
Oh dear.. I'm passing in an INode object. At some point I'm going to have to downcast that to the correct node type so the dialog can use it properly.
I've studied the "PostgreSQL Admin 3" source code, and they do something similar to this. They get round it by doing something like this:
FooObjectFactoryClass::createDialog(IObject *object)
{
FooObjectDialog *dialog = new FooObjectDialog((FooObject*)object);
}
Yeck.. cast!
The only way I can think around it and still able to use my factories is to inject the node itself into the factory before it is returned:
FooNode : INode
{
FooNodeFactory* FooNode::getFactory()
{
fooNodeFactory->setFooNode(this);
return fooNodeFactory;
}
}
So then my edit event can do this:
void onEditClicked()
{
IFactory *factory = selectedNode->getFactory();
Dialog *dialog = factory->createEditDialog(parentWidget);
dialog->show();
}
And it will use the injected node for context.
I suppose if there is no injected code, the createEditDialog could assert false or something.
Any thoughts?
Thanks!