User Tools

Site Tools


2015_2016:s3:concprogobjet:td:td2

TD3 : qui est Responsable?

Objectifs : Travailler sur de petits exemples différents points d'un développement pragmatique.

Responsabilités : Analyse et développement de la partie "Métier"

Le bus est maintenant composé de boîtes à messages.

  • Un agent demande à créer un bus en précisant son nom. Si un bus avec ce nom existe déjà, il ne se passe rien.
  • Un agent peut demander s'il existe un bus de nom donné.
  • Un agent peut lister les noms des bus existants.
  • Un agent demande à créer une boîte à messages associée à un bus en précisant le nom de la boite. Si la boite existe déjà, il ne se passe rien.
  • Un producteur envoie un message vers un bus et éventuellement vers une boîte de messages spécifique du bus, en précisant leurs noms et le contenu du message. En l'absence de boîte de message, le message est posté dans la boite par défaut.
  • Un consommateur peut demander à lire des messages qui se trouvent dans une boîte sur un bus
  • Un consommateur peut demander à lire tous les messages qui se trouvent sur le bus.
  • Une boîte ne peut pas être associée à plusieurs bus. Un bus peut évidemment avoir plusieurs boîtes.

Pour vous aider vous pouvez dans un premier temps, ne pas tenir compte de la boîte de messages par défaut et n'en tenir compte qu'à la fin du TD en identifiant bien les impacts sur le modèle et sur le code, en particulier avec les responsabilités qui en résultent.
  1. Quels modèles utilisez-vous pour analyser le problème ?
  2. Dans vos diagrammes de séquences, faîtes bien apparaître les interfaces graphiques et les contrôleurs mais dans les diagrammes de classe concentrez vous uniquement sur la partie métier dans un premier temps.
  3. Qui est responsable de retrouver un bus à partir de son nom ? une boite de messages? (pattern expert)
  4. Qui est responsable de créer un bus? une boite de message? pourquoi? (Pattern créateur)
  5. Qui est responsable de créer un message ? pourquoi? (Pattern créateur)
  6. Avez-vous des relations bi-directionnelles? Si oui, avez-vous décidé de qui est le “maître” et de qui est l'“esclave”?
  7. Avez-vous bien prévu les tests unitaires? Que se passe-t-il si vous demandez
    1. à lire les messages sur une boîte qui n'existe pas?
    2. à créer un bus d'un nom déjà utilisé?
  8. A partir de maintenant, on s'intéresse au scénario suivant, sans tenir compte de l'interface graphique, est-ce que vous pouvez l'implémenter, revenez sur votre code si besoin (Vous pouvez vous aider des tuyaux donnés plus bas si besoin):
    1. Je crée un bus “NiceInformation”
    2. Je crée une boite “Circulation” sur le bus “NiceInformation”
    3. Je poste un message “Embouteillage” dans la boite “Circulation” du bus “NiceInformation”
    4. Je poste un message “Nouveau rond point” dans la boite “Circulation” du bus “NiceInformation” 1)
    5. Je lis les messages qui se trouvent dans la boite “Circulation”, i.e. je récupère les messages.
    6. Je demande à effacer les messages de la boite “Circulation” du bus “NiceInformation” 2)
    7. Je poste un message “SoireeIUT” sur le bus “NiceInformation”
    8. J'attends 2s (Thread.sleep(2000));
    9. Je poste un message “SoireeIntegrationIUT” sur le bus “NiceInformation”
    10. J'attends 2s (Thread.sleep(2000));
    11. <Optionnel> Je demande à effacer tous les messages postés depuis plus de 4s sur le bus “NiceInformation”
  9. Regardez vos codes, et vérifiez que vous avez bien respecté la loi de Demeter3). Si ce n'est pas le cas, corrigez vos codes.
  10. Comment avez-vous géré la boîte par défaut? (Avez-vous pensé à définir des constantes?)
  11. Pouvez-vous décrire chacune de vos classes avec une seule phrase? Faîtes-le dans les commentaires de vos classes.

Architecture : Interface graphique et contrôleur

L'objectif est ici de décomposer l'application pour que :

  • Le programme principal consiste à créer créer un controleur et à le démarrer.
	public static void main(String[] args) throws Exception {
		Controleur c = new Controleur();
		c.start();
	}
  • L'interface n'interagit jamais directement avec le métier.
    • Elle ne connait pas non plus le contrôleur dans cet exercice.
    • Voici un exemple de code pour l'interface. Pour se concentrer sur l'architecture, l'interface est une classe Java qui utilise Scanner pour lire au clavier et System.out.print… pour l'affichage.
  • Le contrôleur joue le rôle de chef d'orchestre entre le métier et l'interface.
    • Il ne peut pas utiliser System.out…; tout affichage passe par l'interface.
    • Il n'a pas le droit de modifier la partie métier sans passer par des objets métiers.
    • Il n'est pas autorisé à stocker la liste des bus etc. Pensez à utiliser le principe de délégation.
    • Voici des extraits de code pour vous aider ci-après.
public class Controleur {
 
	private Gestionnaire registre = new Gestionnaire();
	private UserConsole ui = new UserConsole();
 
    public void start() throws Exception {
        String commande = ui.lireCommande();
        switch (commande.charAt(0)) {
            case UserConsole.COM_CREER_FORUM:
                creerForum();
                start();
                break;
            case UserConsole.COM_CREER_CANAL :
                creerCanal();
                start();
                break;
            case UserConsole.COM_POSTER_MESSAGES:
                posterMessage();
                start();
                break;
            case UserConsole.COM_LIRE_MESSAGES:
                lireMessage();
                start();
                break;
            case UserConsole.COM_STOP:
                ui.afficher("Au revoir ");
                Memoire.save(registre, "sauvegarde.txt");
                exit(0);
                break;
            default :
                ui.afficher("La commande spécifiée n'existe pas\n");
                sleep(1000);
                start();
        }}
  1. Développez le code correspondant.
  2. Quel type de contrôleur avez-vous défini en respectant les directives données?
  3. Vous devez à présent pouvoir jouer le scénario précédent en utilisant votre interface graphique.
  4. Visualisez votre code correspondant à la création d'un forum sous la forme d'un diagramme de séquences.
    Outils ⇒ Code ⇒ Instant Reverse to sequence diagram
  5. Pouvez-vous décrire chacune de vos classes avec une seule phrase? Faîtes-le dans les commentaires de vos classes.

Architecture : Persistance simplifiée

1- On désire sauvegarder l'ensemble des forums à chaque fin d'exécution du programme principal et recharger l'état des forums à chaque lancement du programme principal.

Vous pouvez utiliser le code suivant. Pour l'utiliser il suffit que vos classes “implements Serializable'.

Exemple de sauvegarde :

 Memoire.save(registre, NomFichier);

Exemple de lecture :

        Object o  = Memoire.read(NomFichier);
        if (o instanceof Gestionnaire){
                registre = (Gestionnaire) o;}
    }

Evolutions

  1. Dans certaines boites dès qu'un message est lu, il est effacé. Modifier votre code pour permettre la création de telles boites. Attention, les autres boîtes sont toujours utilisables. Utilisez bien les tests unitaires, pour vérifier que vous ne “cassez” pas vos codes. Comment votre modèle est-il modifié?
  2. Pour certains Bus, lorsque l'on poste un message en donnant comme nom de boite “*”, le message est posté dans toutes les boites. Modifier votre code pour tenir compte de ce nouveau besoin.
  3. Analyser les dépendances entre vos classes.

Rendus

Le …

  • Mettez un mail à votre encadreur avec soit l'adresse où récupérer le TD soit le TD lui-même, dans le sujet du mail [S3T][TD3] Noms des participants au rendu :
  • De préférence utilisez la boite de dépôt pour Mme Blay avec date limite : le 6 octobre à minuit.
  • Le rendu consiste en :
    1. Un document contenant
      • votre modèle final (Tout le monde n'aboutit pas au même modèle, c'est certain)
      • des explications sur les raisons de ce modèle, les choix que vous avez faits et les leçons apprises.
    2. Les codes et les tests.
    3. Il est préférable que les codes soient commentés en respectant les consignes d'une javadoc 4)

Dans cet exercice nous évaluons votre capacité à concevoir les bons modèles et la “bonne” architecture relativement à vos objectifs. Des modèles incomplets sont évidemment considérés comme faux au regard de ces objectifs.

Tuyaux

Vous avez besoin dans ce TD de manipuler des collections et des dates, voici quelques tuyaux que vous pourriez retrouver sur le Web et qui sont extraits des codes que nous avons mis en oeuvre pour ce TD. Vous pouvez évidemment avoir d'autres solutions :

  • Pour parcourir une ArrayList (le for qui suit)
  • Pour pouvoir effacer dans une liste que l'on parcourt, il faut d'abord en faire une copie
ArrayList<Message> messagesContenus = new ArrayList<Message>(messages);
        for (Message m : messagesContenus) {
            if (m.perime(i)) {
                m.detruire();
                messages.remove(m);
            }
  • Une manière “facile” pour savoir si un message est périmé de plus de x secondes :
  public boolean estPerime(int second){
        Date d = new Date();
        long ms = d.getTime();
        ms = ms - second*1000;
        d.setTime(ms);
        return this.dateEmission.before(d);
    }
  • Si vous avez utilisé des HashMap vous avez peut être besoin de récupérer la liste des objets contenus comme par exemple :
    public void detruireMessages(int i) {
       for (Boite b : boites.values()) {
           b.detruire(i);
       }
1) , 2)
pareil pour le bus “AntibesInformation”, ça passe?
3)
Quand on l'aura vu en cours
4)
utilisez simplement eclipse pour générer la stucture des commentaires par exemple
2015_2016/s3/concprogobjet/td/td2.txt · Last modified: 2018/09/16 23:08 by blay