Я использую абстрактную фабрику для создания компонентов пользовательского интерфейса, таких как диалоги.Используемая абстрактная фабрика возвращается из выбранного в настоящий момент универсального «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 Admin 3", и они делают что-то похожее наэтот.Они обошли его, сделав что-то вроде этого:
FooObjectFactoryClass::createDialog(IObject *object)
{
FooObjectDialog *dialog = new FooObjectDialog((FooObject*)object);
}
Йек .. брось!
Единственный способ, которым я могу обдумать это и при этом использовать свои фабрики, - это ввести узелсам в фабрику, прежде чем он будет возвращен:
FooNode : INode
{
FooNodeFactory* FooNode::getFactory()
{
fooNodeFactory->setFooNode(this);
return fooNodeFactory;
}
}
Итак, мое событие редактирования может сделать это:
void onEditClicked()
{
IFactory *factory = selectedNode->getFactory();
Dialog *dialog = factory->createEditDialog(parentWidget);
dialog->show();
}
И он будет использовать вставленный узел для контекста.
Полагаю, что если нет внедренного кода, createEditDialog мог бы утверждать ложь или что-то в этом роде.
Есть мысли?
Спасибо!