Sto usando una fabbrica astratta per creare componenti dell'interfaccia utente come finestre di dialogo. Il factory astratto utilizzato viene restituito da un "INode" generico attualmente selezionato che è la classe base per diversi tipi di nodi. Così, per esempio, se voglio aggiungere un nuovo nodo dello stesso tipo come il nodo selezionato, lo scenario più o meno così:Problema utilizzando la fabbrica astratta
(si prega di notare che questo è il codice semi-pseudo) scatta
utente nodo e il nodo viene memorizzato per un uso successivo:
void onTreeNodeSelected(INode *node)
{
selectedNode = node;
}
utente fa clic su "add" sull'interfaccia utente:
void onAddClicked()
{
IFactory *factory = selectedNode->getFactory();
Dialog *dialog = factory->createAddDialog(parentWidget);
dialog->show();
}
che tutto sembra bene. Il problema arriva quando voglio modificare il nodo selezionato:
void onEditClicked()
{
IFactory *factory = selectedNode->getFactory();
Dialog *dialog = factory->createEditDialog(selectedNode, parentWidget);
dialog->show();
}
Oh caro .. Sto passando un oggetto INode. A un certo punto dovrò ridimensionarlo al tipo di nodo corretto in modo che la finestra di dialogo possa usarlo correttamente.
Ho studiato il codice sorgente "PostgreSQL Admin 3" e fanno qualcosa di simile a questo. Si aggirano facendo qualcosa del genere:
FooObjectFactoryClass::createDialog(IObject *object)
{
FooObjectDialog *dialog = new FooObjectDialog((FooObject*)object);
}
Yeck .. cast!
L'unico modo che posso pensare intorno ad esso e ancora in grado di utilizzare le mie fabbriche è quello di iniettare il nodo stesso nella fabbrica prima di essere restituito:
FooNode : INode
{
FooNodeFactory* FooNode::getFactory()
{
fooNodeFactory->setFooNode(this);
return fooNodeFactory;
}
}
Allora la mia modifica evento può fare questo:
void onEditClicked()
{
IFactory *factory = selectedNode->getFactory();
Dialog *dialog = factory->createEditDialog(parentWidget);
dialog->show();
}
E utilizzerà il nodo inserito per il contesto.
Suppongo che se non vi è alcun codice inserito, createEditDialog potrebbe affermare false o qualcosa del genere.
Qualche idea?
Grazie!