我正在为从Node
类创建的某些数据创建 GUI生成器。每个Node
子类都代表不同类型的数据(例如StringNode,IntNode)。
在运行时,我不知道节点的派生类型。我觉得我唯一的解决方案是拥有大量if
语句列表:
if (auto stringNode = dynamic_cast<StringNode*>(node)) {
/* Generate text input */
} else if (auto intNode = dynamic_cast<IntNode*>(node)) {
/* Generate spin box */
}
// etc...
这似乎效率低下,需要仔细排序,因此派生类型位于它们继承的类型之上。
还有另一种使用多态性的方法吗?
GUI生成器不在定义Node
的库中。
每个节点的GUI可能对于派生类型(例如日期选择器)是唯一的。
我无法在节点上添加虚拟generateGui()
方法,因为这将需要在库中生成GUI。
我可以编辑Node
类。
Node
子类,并且还应允许生成其GUI。
我看过Visitor Pattern和Strategy Pattern,但我认为它们并不适合,因为并非所有类都可以使用,或者GUI生成器在库中不可用。
答案 0 :(得分:0)
我可以提供此实现:
enum class NodeType { Unknown, String, Int, Float };
using CreateFunc = void(*)(Node *node);
using TypeFunc = bool(*)(Node *node);
// define type-checkers:
bool IsStringNode(Node *node)
{
return dynamic_cast<StringNode*>(node) != nullptr;
}
bool IsIntNode(Node *node)
{
return dynamic_cast<IntNode*>(node) != nullptr;
}
bool IsFloatNode(Node *node)
{
return dynamic_cast<FloatNode*>(node) != nullptr;
}
class GuiGenerator
{
public:
// define specific creators:
static void CreateStringGui(Node *node) { cout << "Creating String Gui" << endl; }
static void CreateIntGui(Node *node) { cout << "Creating Int Gui" << endl; }
static void CreateFloatGui(Node *node) { cout << "Creating Float Gui" << endl; }
//void Create(<Some other node>) {}
};
map<NodeType, CreateFunc> Creators =
{
{ NodeType::String, &GuiGenerator::CreateStringGui },
{ NodeType::Int, &GuiGenerator::CreateIntGui },
{ NodeType::Float, &GuiGenerator::CreateFloatGui }
};
NodeType GetType(Node *node)
{
vector<pair<NodeType, TypeFunc>> types =
{
{ NodeType::String, &IsStringNode },
{ NodeType::Int, &IsIntNode },
{ NodeType::Float, &IsFloatNode }
};
for(auto &a : types)
if(a.second(node))
return a.first;
return NodeType::Unknown;
}
// And here is it: your simplified function
//
static void CreateGUI(Node *node)
{
auto type = GetType(node);
Creators[type](node);
}
您可以像这样使用它:
Node *node1 = new StringNode();
Node *node2 = new IntNode();
Node *node3 = new FloatNode();
CreateGUI(node1);
CreateGUI(node2);
CreateGUI(node3);
没有提供用于简化的错误处理。