:: Enseignements :: Master :: M1 :: 2019-2020 :: Programmation Orientée Objet - Design Patterns ::
[LOGO]

ça vaut le détour


Ce TD se déroule en autonomie. Les rendus sont à faire sur la plate-forme elearning. Les consignes précises du rendu : Rappel : le travail en autonomie peut inclure des discussions entre vous mais le résultat / le rendu doit être le résultat de VOTRE compréhension.

Exercice 1 - Questions

Les réponses aux questions doivent être faites en 15 minutes maximum Ne faites pas de copier/coller Wikipedia ! ce qui nous intéresse, c'est votre compréhension et vos mots !

  1. #EXPLICATIONS Selon vous, quel est l'avantage principal du design pattern Visitor
  2. #EXPLICATIONS Selon vous, quel est l'inconvénient principal du design pattern Visitor
  3. #EXPLICATIONS Parcourez la javadoc sur ElementVisitor. Exprimez brièvement votre compréhension.

Exercice 2 - Encore une calculette !

Le but de cet exercice est modifier un code existant permettant d'effectuer le calcul d'une expression en polonaise inverse dans le but de fermer la hiérarchie d'expression tout en laissant la possibilité à un utilisateur d'écrire ses propres traitements.

Le code suivant permet d'évaluer une expression en polonaise inverse
     Iterator<String> it = Pattern.compile(" ").splitAsStream("+ * 4 + 1 1 + 2 3").iterator();
     Expr expr = Expr.parseExpr(it);
     System.out.println(expr);
     System.out.println(expr.eval());
    

  1. #EXPLICATIONS Dessinez l'arbre d'expressions créé par le code ci-dessus puis dessinez sur l'arbre l'évaluation de l'expression (c'est-à-dire un appel à la méthode eval()).
    Faite une photo du résultat.
  2. #CODE En lisant l'article wikipedia sur le Visitor Pattern (et sa section Java example), modifiez le code pour introduire le visiteur ExprVisitor, comme déclaré ci-dessous.
          public interface ExprVisitor {
            public int visitValue(Value value);
            public int visitBinOp(BinOp binOp);
          }
         

    #CODE Puis ecrivez une classe EvalExprVisitor qui effectue l'évaluation en utilisant le visitor pattern plutôt qu'en utilisant la méthode eval.
    Une fois que l'EvalExprVisitor fonctionne, supprimez la méthode eval de l'interface Expr (et des sous classes).
  3. On souhaite faire la même transformation mais avec la méthode toString à la place de la méthode eval. Comme toString retourne une String et pas un int comme eval, il faut paramétrer l'interface ExprVisitor par le type de retour comme ceci.
          public interface ExprVisitor<R> {
            public R visitValue(Value value);
            public R visitBinOp(BinOp binOp);
          }
         

    #CODE Modifiez votre code pour utiliser la version paramétrée de l'interface ExprVisitor ci-dessus.
    Vous pouvez utiliser la classe ElementVisitor comme modèle !
    #CODE Ecrivez une classe ToStringVisitor qui effectue le même travail que toString puis retirez les méthodes toString une fois que le visiteur marche.
  4. Le toStringVisitor que vous avez écrit (comme les méthodes toString qu'il y avait précédemment) n'est pas très efficace car il y a beaucoup de création de String intermédiaire, il serait préférable d'utiliser un seul StringBuilder pour tout le calcul.
    #CODE Modifiez le ToStringVisitor pour n'utiliser qu'un seul StringBuilder.
    Note: cela veut peut-être dire modifier l'interface ExprVisitor ou pas, il y a plusieurs solutions, essayer de venir avec la votre.

Exercice 3 - Le visiteur avec des lambdas

Revenons sur ce qu'est un visteur, un visteur est un objet qui associe à une classe (Value ou BinOp) un code à exécuter. Il peut donc être implanté avec une table de hachage qui associe à une classe (un objet de type java.lang.Class) une lambda contenant le code à exécuter.
On se propose d'écrire la classe ExprVisitor de tel sorte à ce que le code suivant fonctionne
     ExprVisitor<Integer> evalVisitor = new ExprVisitor<>();
     evalVisitor
       .when(Value.class, value -> {
         ...
       })
       .when(BinOp.class, binOp -> {
         ...
       });
     evalVisitor.call(expr); 
     

  1. #EXPLICATIONS Quel sont le ou les avantages de l'API proposée par rapport à une API de visiteur classique ?
  2. #EXPLICATIONS Quelle doit être la signature de la méthode when ?
    #EXPLICATIONS Quel est le type du second paramètre de la méthode when ?
  3. #EXPLICATIONS Quelle est la signature de la méthode call ?
  4. #EXPLICATIONS Quelle structure de donnée doit être utilisée pour implanter les méthodes when et call ?
    #CODE Ecrire en pseudo code, les codes de when et call.
    #EXPLICATIONS Comment déclarer la structure de données pour éviter de faire des casts ?
    #CODE Ecrire le code Java de la classe ExprVisitor.
  5. #EXPLICATIONS Quelle sont les avantages et inconvénients d'écrire le code du visiteur de cette façon là par rapport au visteur classique du GOF ?