我正在使用抽象工廠創建用戶界面組件,如對話框。所使用的抽象工廠從當前選擇的通用「INode」返回,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);
}
Yeck .. cast!
我能想到繞過它,仍然可以使用我的工廠唯一的辦法是到節點自身注入到工廠返回之前:
FooNode : INode
{
FooNodeFactory* FooNode::getFactory()
{
fooNodeFactory->setFooNode(this);
return fooNodeFactory;
}
}
所以後來我的編輯事件可以這樣做:
void onEditClicked()
{
IFactory *factory = selectedNode->getFactory();
Dialog *dialog = factory->createEditDialog(parentWidget);
dialog->show();
}
它將使用注入的節點作爲上下文。
我想如果沒有注入代碼,createEditDialog可能會聲明錯誤或其他東西。
有什麼想法?
謝謝!