迭代节点的层次结构 - 访问者和复合体?

时间:2009-02-11 21:20:58

标签: c++ oop design-patterns composite visitor

让我们假设我有一组节点,我稍后会用于我的Renderer类。然后我有一个访问者类,可以访问节点或整个集合。它很简单,因为我的节点集合只是std :: list的包装器,只需要很少的额外方法。

问题是我想为节点(而不是简单列表)建立树状结构,因此节点可以有父节点和n个子节点。这将是方便的,因为我希望能够将一个节点传递给我的Renderer并将所有内容呈现在该节点的“下方”。答案可能是复合材料。

我如何一起使用Visitor和Composite?我已经读过它通常是一个很好的组合,但我的实现看起来很糟糕......我很想念......

3 个答案:

答案 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

处有点冗长

它还展示了如何跳过“不感兴趣”的分支。