Le but de ce TD est de voir les design patterns proxy, composite, dynamic proxy et adapter.
On souhaite gérer, en utilisant une API commune, les fichiers stockés sur le disque
(java.io.File) et les répertoires contenant ceux-ci (java.io.File.
public interface Item { public Directory getDirectory() throws ItemException; public String getName() throws ItemException; } public interface Directory extends Item { public List<Item> getItems() throws ItemException; } public interface File extends Item { public long getLength() throws ItemException; public long getTime() throws ItemException; } public interface ItemFactory { public Item createItem(java.io.File file) throws ItemException; }La classe FactoryException hérite de la classe Exception. On supposera de plus que ni les fichiers ni l'arborescence ne changeront pas en cours de route.
Créer une implantation de l'interface Plant ci-dessous, nommée PlantImpl
public interface Plant { public void setName(String name); public String getName(); public void setAddress(String address); public String getAddress(); }
Implanter un mécanisme utilisant le design-pattern Visitor permettant de parcourir une arborescence d'Item (de l'exercice 1).
Ecrire un visiteur DeepFirstItemVisitor effectuant un parcours en profondeur
et affichant les items.
Modifier le DeepFirstItemVisitor pour qu'il prenne lui-même en paramêtre un visiteur
sur lequel il déléguera les opérations à effectuer (au lieu de l'affichage).
Quel est le design pattern correspondant ?
Au lieu d'afficher un message sur la console, on souhaite que des objets PropertyObserver
puisse s'enregister auprès de la PlantFactory pour être averti des changements
des valeurs des objets Plant.
Renommer la méthode setDebugMode(boolean) en setEventMode(boolean).
On souhaite écrire un classe récupérant les commentaires d'un fichier java. Pour cela on simulera, à l'aide du design-pattern state, l'automate suivant :
Les états de l'automate seront implémentés à l'aide d'une enum. Une transition étiquetée x→y signifie que si l'on lit un x sur l'entrée, on doit ajouter y au commentaire courant. Le symbole ε signifie que l'on ne doit rien ajouter et le symbole ↺ que l'on a atteint la fin d'un commentaire.
On souhaite généraliser le mécanisme précédent pour que l'on puisse utiliser n'importe
quel objet implantant une interface et pas uniquement des Plant.
On laissera la création des objets à la charge de l'utilisateur et l'on ne s'occupera
que d'intercepter les modifications.
Voici la nouvelle interface de la classe PlantFactory renommée pour l'occasion en
GenericEventManager
public class GenericEventManager { <T> T wrap(T object) {...} <T> T unwrap(T object) {...} void addPropertyObserver(PropertyObserver observer) {...} void removePropertyObserver(PropertyObserver observer) {...} }Noter que la méthode setEventMode(boolean) a disparu.
On supposera que dans un premier temps, l'objet de type T n'implante qu'une seule interface.
public interface Product { public void setID(long ID); public long getID(); public void setPlants(Set<Plant> plants); public Set<Plant> getPlants(); }Lorsque l'on ajoute une usine pour un produit, un évènement devra être envoyé :
Product p=new ProductImpl(); p.setPlants(new HashSet<Plant>()); GenericEventManager gem=new GenericEventManager(); p=gem.wrap(p); p.getPlants().add(new PlantImpl()); // genère un évènement d'insertionPS: Bonne chance Jim...