Я использую абстрактную фабрику для создания компонентов пользовательского интерфейса, таких как диалоговые окна. Абстрактная используемая фабрика возвращается из в настоящее время выбираемого универсального "INode", который является базовым классом для нескольких различных типов узла. Так, например, если я хочу добавить новый узел того же типа как выбранный узел, сценарий проходит примерно так:
(обратите внимание, что это - полупсевдо код),
Пользователь нажимает узел, и узел хранится для более позднего использования:
void onTreeNodeSelected(INode *node)
{
selectedNode = node;
}
Пользовательские щелчки "добавляют" в пользовательском интерфейсе:
void onAddClicked()
{
IFactory *factory = selectedNode->getFactory();
Dialog *dialog = factory->createAddDialog(parentWidget);
dialog->show();
}
Который все кажется прекрасным. Проблема возникает, когда я хочу отредактировать выбранный узел:
void onEditClicked()
{
IFactory *factory = selectedNode->getFactory();
Dialog *dialog = factory->createEditDialog(selectedNode, parentWidget);
dialog->show();
}
О, Боже.. Я являюсь передающим в объекте INode. В какой-то момент я оказываюсь перед необходимостью удрученный, что к корректному типу узла, таким образом, диалоговое окно может использовать его правильно.
Я изучил "Администратора PostgreSQL 3" исходных кода, и они делают что-то подобное этому. Они обходят его путем выполнения чего-то вроде этого:
FooObjectFactoryClass::createDialog(IObject *object)
{
FooObjectDialog *dialog = new FooObjectDialog((FooObject*)object);
}
Yeck.. бросок!
Единственным путем я могу думать об этом, и все еще способный использовать мои фабрики должен ввести сам узел в фабрику, прежде чем это будет возвращено:
FooNode : INode
{
FooNodeFactory* FooNode::getFactory()
{
fooNodeFactory->setFooNode(this);
return fooNodeFactory;
}
}
Таким образом мое событие редактирования может сделать это:
void onEditClicked()
{
IFactory *factory = selectedNode->getFactory();
Dialog *dialog = factory->createEditDialog(parentWidget);
dialog->show();
}
И это будет использовать введенный узел для контекста.
Я предполагаю, нет ли никакого введенного кода, createEditDialog мог бы утверждать ложь или что-то.
Какие-либо мысли?
Спасибо!