Programmation Java Avancée

Master M2 TTT --- Feuille n° 4

Visiteur

Exercice n° 1


Écrire une interface Expression qui déclare une méthode accept prenant en argument un Visiteur (que l'on déclarera plus tard) et ne retournant rien.


Exercice n° 2


Une Expression est une expression arithmétique; elle est formée de "nœuds" Addition, Multiplication, Substraction, et Division, et ses "feuilles" sont soit des Value (une valeur est représentée par un double) ou des Variable (représentée par un char). Chacune de ces classes contient une implémentation de la méthode accept qui consiste en la ligne suivante:
  v.visit(this);
Écrire proprement la définition des classes Addition, Value et Variable. Tous les nœuds internes de l'expression ont deux enfants. Que faire pour éviter de définir les mêmes attributs, getters et setters dans chacune de ces classes?




Exercice n° 3


Écrire une interface Visitor, dans laquelle, pour chaque type implémentant Expression, on déclare une méthode visit.


Exercice n° 4


Écrire une classe DisplayVisitor, de sorte que si e est une expression et v un DisplayVisitor, e.accept(v); affiche l'expression avec des parenthèses.
Par exemple (3.4 + (x / 5.2)).


Exercice n° 5


Écrire une classe EvalVisitor, dont chaque objet possède une map donnant une valeur à un certain nombre de variables et qui calcule la valeur de l'expression selon cette map. Par exemple, si v est un EvalVisitor tel que x —> 10.4, et e est l'expression donnée en exemple, on veut que
e.accept(v);
System.out.println(v.getValue());
affiche 5.4.
Si une variable n'a pas de valeur connue, au moment de l'appel de la méthode getValue, on lèvera une exception UnassignedVariable en indiquant quelle variable n'avait pas de valeur.
Écrire la définition de l'exception UnassignedVariable.


Exercice n° 6


Si on se sert plusieurs fois de la même variable, on veut ne créer qu'un seul objet (pour chaque variable). Quelles sont les modifications à apporter à la classe Variable de sorte qu'on n'appelle plus le constructeur, mais une méthode getVariable(char c); qui retourne l'objet correspondant à c.


Exercice n° 7


Plutôt que d'écrire dans chaque classe implémentant Expression la même méthode accept, on voudrait factoriser le code en insérant entre l'interface et les classes une classe abstraite AbstractExpression contenant le code de la méthode accept. Pourquoi cela ne marche-t-il pas avec l'interface Visitor écrite à la question 3 ?


Exercice n° 8


Afin que la modification de la question 7 fonctionne, modifier l'interface Visitor de façon à n'avoir qu'une méthode visit. Afin de ne pas modifier toutes les classes implémentant Visitor, écrire une classe abstraite AbstractVisitor implémentant visit et qui, selon la nature réelle de Expression appelle la bonne méthode dans le visiteur.
Indication: On pourra par introspection avoir accès aux types véritables de l'expression et du visiteur afin d'appeler la bonne méthode.



Sylvain Lombardy