Mar*_*ark 6 c++ oop design-patterns
我有一个左侧有树视图的用户界面,右侧有一个查看器(有点像电子邮件客户端).右侧的查看器显示我在左侧树中选择的任何内容的详细信息.
用户界面具有"添加","编辑"和"删除"按钮.这些按钮的行为取决于树中选择的"节点".
如果我选择了特定类型的节点,并且用户单击"编辑",那么我需要为该特定类型的节点打开相应的编辑对话框,其中包含该节点的详细信息.
现在,有很多不同类型的节点,并且实现访问者类感觉有点乱(当前我的访问者有大约48个条目....).它确实很好用 - 基本上用于编辑类似于继承访问者的OpenEditDialog类,并打开相应的编辑对话框:
abstractTreeNode->接受(OpenEditDialog());
问题是我必须为我想要在节点上执行的每个"动作"实现抽象访问者类,并且出于某种原因我不禁想到我错过了一个技巧.
另一种方法是在节点本身中实现这些功能:
abstractTreeNode->openEditDialog();
Run Code Online (Sandbox Code Playgroud)
我在这附近点了节点,所以也许这更好:
abstractTreeNode->editClickedEvent();
Run Code Online (Sandbox Code Playgroud)
我不禁想到这会污染节点.
我确实想到了第三种方式,我还没有多想过.我可以有一个被添加到树来代替,让我或者叫自由函数来执行任何操作的模板包装类,所以我想,因为它充当节点和接口之间一展身手:
(伪代码在我脑海中只是为了给出一个想法):
template <class T>
TreeNode(T &modelNode)
{
m_modelNode = modelNode;
}
template <>
void TreeNode<AreaNode>::editClickedEvent()
{
openEditDialog(m_modelNode); // Called with concrete AreaNode
}
template <>
void TreeNode<LocationNode>::editClickedEvent()
{
openEditDialog(m_modelNode); // Called with concrete LocationNode
}
Run Code Online (Sandbox Code Playgroud)
等等..
所以这有效地扩展了节点,但以不同的方式使用访问者,它看起来有点整洁.
现在我继续前进,采取使用这些方法之一尝试之前,我想那会是明智的,得到一些输入.
谢谢!我希望这一切都有一定意义..
编辑:
我嘲笑了模板包装的想法..
class INode
{
public:
virtual ~INode() {}
virtual void foo() = 0;
};
class AreaNode : public INode
{
public:
AreaNode() {}
virtual ~AreaNode() {}
void foo() { printf("AreaNode::foo\r\n"); }
};
class RoleNode : public INode
{
public:
RoleNode() {}
virtual ~RoleNode() {}
void foo() { printf("RoleNode::foo\r\n"); }
};
class ITreeNode
{
public:
virtual ~ITreeNode() {}
virtual void bar() = 0;
virtual void foo() = 0;
};
template <class T>
class MainViewTreeNode : public ITreeNode
{
public:
MainViewTreeNode() : m_node() {}
virtual ~MainViewTreeNode() {}
void bar() {}
void foo() { m_node.foo(); }
protected:
T m_node;
};
template <>
void MainViewTreeNode<AreaNode>::bar()
{
printf("MainViewTreeNode<AreaNode>::bar\r\n");
}
template <>
void MainViewTreeNode<RoleNode>::bar()
{
printf("MainViewTreeNode<RoleNode>::bar\r\n");
}
int _tmain(int argc, _TCHAR* argv[])
{
MainViewTreeNode<RoleNode> role;
MainViewTreeNode<AreaNode> area;
std::list<ITreeNode*> nodes;
nodes.push_back(&role);
nodes.push_back(&area);
std::list<ITreeNode*>::iterator it = nodes.begin();
for (; it != nodes.end(); ++it)
{
(*it)->foo();
(*it)->bar();
}
getchar();
return 0;
}
Run Code Online (Sandbox Code Playgroud)
谢谢.
| 归档时间: |
|
| 查看次数: |
391 次 |
| 最近记录: |