【发布时间】:2010-08-02 17:20:55
【问题描述】:
我正在使用抽象工厂来创建用户界面组件,例如对话框。使用的抽象工厂是从当前选择的通用“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 可以断言 false 或其他东西。
有什么想法吗?
谢谢!
【问题讨论】:
标签: c++ design-patterns oop