web-dev-qa-db-fra.com

Design pour un arbre à l'aide d'un motif de visiteur, comment mettre en œuvre différents types de travers?

On m'a demandé une question de conception théorique avec un œil sur les modèles GOF.:

"Compte tenu d'une conception d'un arbre à l'aide d'un modèle de visiteur standard, comment votre conception devrait-elle permettre à un utilisateur de choisir entre les traversiers de pré-commande de l'OM, ​​de commande ou de commande post-commande?"

Je pense que simplement laisser le visiteur, mais donner la traversée à un objet itérateur après le motif itérateur.

L'idée serait de mettre en œuvre 3 itérateurs qui permettent la traversée souhaitée. Ils ont une interface et le visiteur n'a besoin que d'interagir avec cette interface, se donnant un argument à l'itérateur qui fournit une traversée. L'utilisateur peut choisir l'itérateur à utiliser lorsque vous en donnez un au visiteur.

Cela sonne-t-il comme une solution élégante? Des idées meilleures?

7
Sven

Une chose à propos des modèles de visiteurs est une idée fausse, qu'elle est attachée en quelque sorte à la structure de type arbre. Ce qui est tout à fait faux. La question sonne comme si cela faisait juste cela. Donc, la première chose ferait la réparation de cette idée fausse. Et puis je voudrais exactement vous dire que vous l'avez dit. Créez 3 itérateurs différents un pour chaque type de traversé.

Mais cela dépend de la complexité de l'arbre. Si chaque nœud a la même collection spécifiée d'enfants, il est facile. Les problèmes commencent lorsque différents types de nœuds ont une structure différente d'enfants. Ensuite, le visiteur commence à avoir un sens. Mais les différents types d'ordonnance triviation cessent de créer un sens, car ils ne fonctionnent que pour les n-arryers, pas pour les arbres avec des types arbitraires d'enfants dans chaque nœud.

11
Euphoric

Peut-être que je manque quelque chose, mais vous n'avez-vous pas simplement besoin de visiteurs différents pour chacun des types de traversée, PreorderStreevisitor, Inordertreevisitor, PostOrdertreevisitor avec la méthode de visite spécifique au type de traversé. Vous voulez probablement qu'ils prennent des mesures qui pourraient être appliquées à un noeud afin qu'ils deviennent en réalité les itérateurs sur l'arbre.

interface ITreeVisitor {
   void visit(ITreeNode node);
}

interface ITreeNode {
   ITreeNode getLeft();
   ITreeNode getRight();
   int getValue();
   void accept(ITreeVisitor visitor);
}

interface IAction {
   void do(ITreeNode);
}

class TreeNode implements ITreeNode {
   ...
   public void accept(ITreeVisitor vistor) {
      visitor.visit(this);
   }
}

class PreOrderTreeVisitor implements ITreeVisitor {

   private IAction action;

   public PreOrderTreeVisitor(IAction action) {
        this.action = action;
   }

   public void visit(ITreeNode node) {

       action.do(node);

       ITreeNode left = node.getLeft();
       if (left != null) left.accept(this);

       ITreeNode right = node.getRight();
       if (right != null) right.accept(this);
   }
}
5
tvanfosson