2009-02-11 10 views
8

Immaginiamo di avere una collezione di nodi che uso per la mia classe Renderer in seguito. Poi ho una classe Visitor che può visitare il nodo o l'intera collezione. È semplice perché la mia collezione di nodi è semplicemente un wrapper di std :: list con alcuni metodi extra.Iterazione gerarchia dei nodi - Visitatore e Composito?

Il problema è che mi piacerebbe avere una struttura ad albero per i nodi (invece di una semplice lista) in modo che un nodo possa avere un genitore e n figli. Sarebbe utile dato che mi piacerebbe poter passare al mio Renderer un nodo e rendere tutto "sotto" quel nodo. La risposta è probabilmente composita.

Come utilizzare insieme Visitatore e Composito? Ho letto che è spesso una buona combinazione, ma le mie implementazioni sono piuttosto negative ... Mi manca Sth.

risposta

5

Ho qualcosa di molto simile implementato per il nostro sistema. Volevo un modo per comporre la gerarchia di oggetti geometrici e renderli nel volume. Ho usato il pattern composito per comporre la mia descrizione (root era Node e poi derivato child era compositeNode (elenco di Nodi)

CompositeNode ha metodo accept() che accetta un visitatore (Visitor) e quindi all'interno di accept() che fai visitatore-> visita (questo)

Così la gerarchia dei visitatori ha classe base come NodeVisitor e visitatori derivati ​​come RenderVisitor (oggetti rendering), ReportVisitor (informazioni nodo scaricato in testo). La classe base dovrà accettare sia base che tipi di nodi specializzati

Quindi sì, la combo funziona e ho un codice funzionante, ma sono d'accordo sul fatto che il design richiede uno sforzo maggiore rispetto a quello che leggereste online (Wiki o esempio di giocattolo)

Spero che questo aiuti

3

Ecco un semplice esempio:

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); 
    } 
    } 
}; 
+0

Perché stai invocando 'accept's of node child in' NodeVisitor'? – user35443

+0

@ user35443: Perché altrimenti le visite si interrompono e poiché l'OP chiede come combinare Visitor con Composite che deve includere la visita di tutti i nodi nel Composito, altrimenti sarebbe solo Visitor. Informazioni sul visitatore: http://en.wikipedia.org/wiki/Visitor_pattern. Informazioni sul composito: http://en.wikipedia.org/wiki/Composite_pattern –

+0

Sì, ma voglio dire che ho guardato al livello gerarchico per un po ', e dovunque guardassi ho trovato l'iterazione dei membri compositi nei nodi, non Visitatore. – user35443

0

Se si desidera che il visitatore anche conoscere la struttura dell'albero (per esempio la profondità che sta visitando o il percorso dalla radice dell'albero) si potrebbe considerare l'utilizzo del modello di visitatore gerarchico. Questo è un po 'lungo a c2.com wiki

Mostra anche come saltare un ramo' non interessante '.