让我们假设我有一组节点,我稍后会用于我的Renderer类。然后我有一个访问者类,可以访问节点或整个集合。它很简单,因为我的节点集合只是std :: list的包装器,只需要很少的额外方法。
问题是我想为节点(而不是简单列表)建立树状结构,因此节点可以有父节点和n个子节点。这将是方便的,因为我希望能够将一个节点传递给我的Renderer并将所有内容呈现在该节点的“下方”。答案可能是复合材料。
我如何一起使用Visitor和Composite?我已经读过它通常是一个很好的组合,但我的实现看起来很糟糕......我很想念......
答案 0 :(得分:5)
我为我们的系统实现了非常类似的东西。我想要一种组合几何对象层次结构并将它们渲染到体积中的方法。我使用复合模式来编写我的描述(root是Node,然后派生的子是compositeNode(节点列表)。
CompositeNode有方法accept()接受访问者(访问者),然后在accept()内部访问者 - >访问(this)。
因此,您的访客层次结构具有基类作为NodeVisitor,派生访问者如RenderVisitor(呈现对象),ReportVisitor(将节点信息转储到文本中)。您的基类需要接受基类和专用节点类型。
所以是的,组合工作,我有工作代码,但我同意设计需要比在线阅读(Wiki或玩具示例)更多的努力。
希望这有帮助
答案 1 :(得分:3)
这是一个简单的例子:
struct NodeVisitor;
struct Node
{
virtual ~Node() {}
virtual void accept(NodeVisitor &v);
};
struct CompositeNode : public Node
{
virtual void accept(NodeVisitor &v);
std::list<NodePtr> nodes_;
};
struct NodeVisitor
{
virtual ~NodeVisitor() {}
virtual void visit(Node &n) = 0;
virtual void visit(CompositeNode &cn)
{
for(std::list<NodePtr>::iterator it = cn.nodes_.begin(), end = cn.nodes_.end(); it != end; ++it)
{
(*it)->accept(*this);
}
}
};
答案 2 :(得分:0)
如果您希望访问者也知道树的结构(例如,它正在访问的深度或来自树根的路径),您可以考虑使用分层访问者模式。 这在c2.com wiki
处有点冗长它还展示了如何跳过“不感兴趣”的分支。