Проблема с помощью абстрактной фабрики

Я использую абстрактную фабрику для создания компонентов пользовательского интерфейса, таких как диалоговые окна. Абстрактная используемая фабрика возвращается из в настоящее время выбираемого универсального "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 мог бы утверждать ложь или что-то.

Какие-либо мысли?

Спасибо!

6
задан Mark 2 August 2010 в 17:20
поделиться