Table of Contents
TD Introduction aux "Design Patterns" et Réutilisation
Objectifs :
- Conforter votre compréhension des différentes formes de réutilisation
- Utilisation du pattern Adapter
- Utilisation du pattern Observer
Nous y passerons seulement 2 séances. Il est conseillé de commencer à travailler de suite !
Présentation générale
Votre défi
Faire passer les tests sans les modifier si ce n'est la référence à la classe “SocialNetwork” qui implémente SocialNetworkInterface et en développant un code propre.
Voici les archives : 1)
- les classes de manipulation des graphes:
- les classes du package grapheX, vous en avez besoin pour l'exécution, mais vous n'avez pas besoin de les comprendre.
- les classes du package grapheSimple vous allez en avoir besoin. Regardez bien ces classes et construisez rapidement le modèle de classes correspondant, par exemple avec ObjectAid),
- les classes définissant le réseau Facebookghost
- les interfaces à implémenter pour faire passer les tests
- les classes de tests :
- celle sur les graphes pour vérifier dans l'archive
graphesimple
- Fixez le setup en ajoutant JUnit 5; exécutez les tests
Vous n'avez que deux interfaces à implémenter :
SocialNetworkInterface
et MemberInterface
.
Ce qui suit est là pour vous aider. }}
Réutilisation par composition et héritage
- Rechercher des relations entre ses membres revient à parcourir le graphe.
- Utilisez la classe
GrapheSimple
2).
- Vous devez construire un réseau social dont les spécifications sont les suivantes (cf. Interfaces SocialNetworkInterface et MemberInterface):
- un réseau social est un ensemble de membres qui sont en relation;
- un membre a un nom, une localisation (String)
et une introduction (String); - Un membre a est en relation avec membre b avec une force entre Faible (LOW) et Très forte (STRONG). Plus la relation est forte plus on considère que la distance est courte. La classe Strength qui représente cette force vous est donnée.
- a peut se considérer en relation avec b à la force STRONG et b ne pas se considérer en relation avec a!
- On veut pouvoir savoir quels sont les membres en relation avec un membre au rang X :
- exemple : a → b → c → a :
- a est en relation avec b au rang 1 (on parcourt un seul arc);
- a est en relation avec c au rang 2 (on parcourt deux arcs);
- c est relation avec a au rang 1; etc.
- Méthode :
relateToRank(MemberInterface member, int rank)
- On veut pouvoir calculer la distance entre 2 personnes, en choisissant la plus courte distance :
- exemple : a –STRONG(1)–> b –LOW(4)–> c et a –HIGH(2)–> d –LOW(4)→ c :
- la distance est : de 1 entre a et b ; de 2 entre a et d;
- la distance est de 5 entre a et c (1 + 4 qui est plus court que 2+4 )
- Méthode :
distance(MemberInterface de, MemberInterface a)
)
- D'autres méthodes doivent être définies, il suffit de lire l'interface “SocialNetworkInterface”.
Réutilisation par adaptation
- On veut intégrer dans notre réseau social, des membres du réseau
facebookGhost
. Lisez bien toute la suite avant de commencer.- Les classes du package facebookGhost s'inspirent très fortement de l'interface fournie par Facebook. En cela, elles se comportent comme un “Mock” simplifié qui pourrait être remplacé par le véritable réseau Facebook à terme3). ).
- On veut ajouter dans notre réseau des membres qui correspondent à des “Users” du réseau facebookGhost (FG). Pour cela, il suffit de créer le membre en déclarant qu'il existe dans un autre réseau4);
- le nom du “User” dans le reseau facebookGhost (name) devient le nom du membre dans notre réseau (nom)
- l'accès à sa localisation correspondent à sa “Home” dans FG. La localisation peut évoluer dans FG. Nous voulons donc qu'elle soit toujours à jour dans notre réseau. Que faire? En tous cas, IL NE FAUT PAS simplement recopier ces valeurs dans le membre de notre réseau. ;
- on “récupère” dans notre réseau, les relations définies dans le réseau FG lorsque
- les users ciblés sont connus de notre réseau, c'est à dire que nous avons déjà un membre de même nom;
- elles correspondent à des relations familiales ou des relations d'amitiés. Par défaut, une relation de famille correspond à une relation de force HIGH dans notre réseau et celle d'amitié ont une force MEDIUM.
- Nous considérons que les relations inverses existent également dans notre réseau. Donc si Peter est ami avec John dans FG, dans notre réseau Peter est en relation avec John par un lien Medium et John est en relation avec Peter avec un lien Medium.
- Quand on ajoute dans notre réseau un membre correspondant au réseau FG, on recherche parmi ses relations directes dans FG s'il existe des “users” connus de notre propre réseau et on lui ajoute les relations si elles n'existaient pas, exemples :
- Exemple : Hercule est connu du réseau FG et se déclare comme membre de notre réseau (
addMember(“Hercule”, FG)
)- On récupère sa famille (Zeus, Alcmène) et ses amis (Admète)
- Seuls Zeus et Admete sont connus de notre réseau; la relation de Hercule vers Zeus est ajoutée avec une force HIGH (lien de famille), celle entre Hercule et Admete est ajoutée avec une force MEDIUM (lien d'amitié); nous mettons également à jour les relations inverses avec la même force.
Réutilisation par observation
Le réseau FG évolue. De nouvelles relations sont régulièrement créées et notre propre réseau peut alors devenir obsolète si les membres impliqués font partie de notre réseau et que nous n'enregistrons pas ces changements de relations. Mais bien sûr, il est impossible de modifier les codes du réseau FG….
Heureusement, le réseau FG est observable. On peut donc demander à être notifié des modifications du réseau FG! Chaque fois qu'une nouvelle relation est ajoutée dans FG on veut vérifier si les “users” mis en relation existent dans notre réseau et si c'est le cas on crée les relations correspondantes dans notre réseau.
Il suffit donc de déclarer notre réseau comme “Observer” du réseau FG et à chaque notification d'ajout d'une relation, de mettre à jour notre propre réseau si c'est nécessaire.
Facultatif & Difficile : Chaque fois qu'un nouveau user est ajouter dans FG, on veut vérifier s'il existe déjà dans notre réseau et si c'est le cas le “connecter” à notre réseau … En fait si vous avez utilisé un adaptateur comme étant un extends de Member, vous ne pourrez pas le faire facilement.
A vous, tout seul ! (5mn)
Nous désirons contrôler l'activité de notre réseau. A terme nous envisageons de suivre cette activité selon plusieurs aspects (afficheur sous forme de courbes de création des membres dans le temps; lever d'alertes lorsque le nombre de relations sur un membre est important; …).
Pour l'instant, nous vous demandons d'afficher chaque fois qu'un nouveau membre ou qu'une relation est créée et bien sûr l'affichage ne se fait pas dans vos codes d'implementation du réseau.
Voici un exemple de début de trace :
New Member created Member [age=20, description=l'ami, nom =Admete] New Member created Member [age=20, description=le dieu ..., nom =Zeus] New Member created Member [age=20, description=la femme de zeus, nom =Hera] New Relation created (3:Member [age=20, description=le hero, nom =Hercule], Member [age=20, description=l'ami, nom =Admete]) New Relation created (3:Member [age=20, description=l'ami, nom =Admete], Member [age=20, description=le hero, nom =Hercule]) New Relation created (2:Member [age=20, description=le hero, nom =Hercule], Member [age=20, description=le dieu ..., nom =Zeus]) New Relation created (2:Member [age=20, description=le dieu ..., nom =Zeus], Member [age=20, description=le hero, nom =Hercule]) New Member created Member [age=20, description=le hero, nom =Hercule] New Relation created (2:Member [age=20, description=le dieu ..., nom =Zeus], Member [age=20, description=la femme de zeus, nom =Hera]) New Relation created (2:Member [age=20, description=la femme de zeus, nom =Hera], Member [age=20, description=le dieu ..., nom =Zeus]) New Member created Member [age=0, description=Asterix, le plus intelligent, nom =Asterix] New Member created Member [age=0, description=falbala, la plus jolie, nom =Falbala] New Member created Member [age=0, description=Obelix, le plus intelligent, nom =Obelix] New Member created Member [age=0, description=Panoramix, le plus magique, nom =Panoramix] New Member created Member [age=0, description=Abraracourcix, chef du village, nom =Abraracourcix]
Remarque
Dépréciation des Interfaces Observer et Observable en Java 9. This class and the Observer interface have been deprecated. The event model supported by Observer and Observable is quite limited, the order of notifications delivered by Observable is unspecified, and state changes are not in one-for-one correspondence with notifications.
Ce n'est pas grave. Si vous avez compris les principes du Patron, vous pourrez les retrouver dans d'autres paradigmes tels que les files d’attente (queues), les sémaphores (semaphores ), ou les gestionnaires d'évènements dans java.beans
package.