Voici un diagramme UML en conception.
Des codes vous sont donnés pour vous aider à comprendre et à ne pas perdre de temps. L'objectif n'est pas de vous apprendre à écrire des boucles ou des algorithmes, mais davantage de bien architecturer vos applications.
public class Professeur { private String nom; private String titre; public Professeur(String nom, String titre) { this.nom = nom; this.titre = titre; } //Pour que l'affichage d'un Professeur soit lisible. Cette méthode est appelée par défaut. public String toString() { return "Professeur [nom=" + nom + ", titre=" + titre + "]"; } }
public class Cours { private String intitule; private Professeur responsable; public Professeur getResponsable() { return responsable; } public void setResponsable(Professeur responsable) { this.responsable = responsable; } //Constructeur public Cours(String intitule, Professeur responsable) { this.intitule = intitule; this.responsable = responsable; } //Pour que l'affichage d'un cours soit "lisible" public String toString() { return "Cours [intitule=" + intitule + ", responsable=" + responsable +"]"; }
public class TestCours { public static void main(String[] args) { System.out.println("===================== Etape 1 ================================="); Professeur prof = new Professeur("Tournesol", "academicien"); System.out.println("Professeur [nom=Tournesol, titre=academicien] = \n" + prof); Cours cBD = new Cours("BD", prof); System.out.println("Cours [intitule=BD, responsable=Professeur [nom=Tournesol, titre=academicien]] = \n" + cBD); System.out.println("=> Un même prof sur deux cours"); Cours cAero = new Cours("aero", prof); System.out.println("Cours [intitule=aero, responsable=Professeur [nom=Tournesol, titre=academicien]] = \n" + cAero); }
Dans ce modèle, l'association apparaît aussi sous la forme d'un attribut (diagramme obtenu par reverse). Pour éviter cela, il faut sélectionner l'attribut, clique droit puis “show as association”
public class Cours { private String intitule; private Professeur responsable; public Professeur getResponsable() { return responsable; } public void setResponsable(Professeur p) { this.responsable = p; } public boolean aUnResponsable(){ return (responsable != null); } //Constructeur public Cours(String intitule, Professeur responsable) { //this.intitule = intitule; this(intitule); // Les codes précédents restent corrects mais on préfère ici une cascade. Uniquement pour les étudiants plus avancés. this.responsable = responsable; } /*Constructeur sans le professeur responsable * puisque à présent il est possible de créer un cours sans responsable. */ public Cours(String intitule) { this.intitule = intitule; } //Pour que l'affichage d'un Cours soit lisible. Cette méthode est appelée par défaut. public String toString() { return "Cours [intitule=" + intitule + ", responsable=" + responsable +"]"; }
A Placer dans le main. Vous pouvez commenter l'étape précédente.
/* Etape 2 */ Professeur amina = new Professeur("AMINA", "missBahut"); Cours cProfs = new Cours("Francais"); System.out.println("Cours [intitule=Francais, responsable=null] = " + cProfs); System.out.println("A un responsable (false) : " + cProfs.aUnResponsable()); cProfs.setResponsable(amina); System.out.println("A un responsable (true) : " + cProfs.aUnResponsable()); System.out.println("Cours [intitule=Francais, responsable=Professeur [nom=AMINA, titre=missBahut]] =\n" + cProfs);
/* Version simple en générant un tableau... à terminer ... */ public class Cours { private Vacataire[] vacataires = new Vacataire[0]; }
Autre solution dans la classe cours
Placer bien vos attributs en début de définition de la classe.
ArrayList<Vacataire> vacataires = new ArrayList<Vacataire>(); public void addVacataire(Vacataire v) { vacataires.add(v); } /** * @param v : Vacataire à retirer de la liste * @return boolean * Retire le vacataire v de la liste (exactement le même objet) si la collection contient cet élément. * Renvoie vrai si la collection contient l'element et La liste des vacataires est modifiée * sinon elle renvoie faux. */ public boolean removeVacataire(Vacataire v) { return (vacataires.remove(v)); } private String vacatairesToString() { String vacatairesString = " "; Iterator<Vacataire> it = vacataires.iterator(); while (it.hasNext()) { vacatairesString += it.next().toString() + ";"; } return "{ " + vacatairesString.substring(0, vacatairesString.length()-1)+ "}"; } public String toString() { return "Cours [intitule=" + intitule + ", responsable=" + responsable + ", vacataires=" + vacatairesToString() + "]"; }
public class Vacataire { private String nom; public Vacataire(String nom) { this.nom = nom; } @Override public String toString() { return "Vacataire [nom=" + nom + "]"; } }
/* Etape 3 */ Cours cBD = new Cours("BD"); System.out.println("Cours [intitule=BD, responsable=null, vacataires={ } = \n" + cBD); Vacataire dolores = new Vacataire("Dolorès"); Vacataire eric = new Vacataire("eric"); System.out.println("=> Pas de retrait possible (false) = " + cBD.removeVacataire(dolores)); System.out.println("Et le cours n'est pas modifié = \n" + cBD); cBD.addVacataire(dolores); System.out.println("=> Ajout pris en compte "); System.out.println("Cours [intitule=BD, responsable=null, vacataires={ Vacataire [nom=Dolorès]}]\n" + cBD); System.out.println("=> Pas de retrait possible de eric(false) = " + cBD.removeVacataire(eric)); System.out.println("=> Retrait pris en compte (true) = "+ cBD.removeVacataire(dolores)); System.out.println("Cours [intitule=BD, responsable=null, vacataires={ }]\n" + cBD); System.out.println("=> Ajouts pris en compte = "); cBD.addVacataire(dolores); cBD.addVacataire(eric); System.out.println("Cours [intitule=BD, responsable=null, vacataires={ Vacataire [nom=Dolorès];Vacataire [nom=eric]}] \n" + cBD); System.out.println("=> Retrait eric pris en compte (true)= "+ cBD.removeVacataire(eric)); System.out.println("Cours [intitule=BD, responsable=null, vacataires={ Vacataire [nom=Dolorès]}]\n" + cBD); cBD.addVacataire(eric); System.out.println("=> Retrait dolores pris en compte = "+ cBD.removeVacataire(dolores)); System.out.println("Cours [intitule=BD, responsable=null, vacataires={ Vacataire [nom=eric]}]= \n" + cBD);
Cours [intitule=BD, responsable=null, vacataires={ } = Cours [intitule=BD, responsable=null, vacataires={ }] => Pas de retrait possible (false) = false Et le cours n'est pas modifié = Cours [intitule=BD, responsable=null, vacataires={ }] => Ajout pris en compte Cours [intitule=BD, responsable=null, vacataires={ Vacataire [nom=Dolorès]}] Cours [intitule=BD, responsable=null, vacataires={ Vacataire [nom=Dolorès]}] => Pas de retrait possible de eric(false) = false => Retrait pris en compte (true) = true Cours [intitule=BD, responsable=null, vacataires={ }] Cours [intitule=BD, responsable=null, vacataires={ }] => Ajouts pris en compte = Cours [intitule=BD, responsable=null, vacataires={ Vacataire [nom=Dolorès];Vacataire [nom=eric]}] Cours [intitule=BD, responsable=null, vacataires={ Vacataire [nom=Dolorès];Vacataire [nom=eric]}] => Retrait eric pris en compte (true)= true Cours [intitule=BD, responsable=null, vacataires={ Vacataire [nom=Dolorès]}] Cours [intitule=BD, responsable=null, vacataires={ Vacataire [nom=Dolorès]}] => Retrait dolores pris en compte = true Cours [intitule=BD, responsable=null, vacataires={ Vacataire [nom=eric]}]= Cours [intitule=BD, responsable=null, vacataires={ Vacataire [nom=eric]}]
import java.util.*; public class Etudiant { private String nom; private int niveau; Collection<Cours> cours = new ArrayList<Cours>(); public Etudiant(String nom, int niveau) { this.nom = nom; this.niveau = niveau; } //Le choix de protected permet d'interdire l'utilisation de cette opération en dehors du package. // Et donc de "potentiellement" éviter une incohérence. // En phase de tests, il serait plus sage de vérifier que le cours a bien connaissance de l'étudiant. protected void addCours(Cours unCours) { cours.add(unCours); } protected void removeCours(Cours unCours) { cours.remove(unCours); } private String coursToString() { String coursString = " "; Iterator<Cours> it = cours.iterator(); while (it.hasNext()) { coursString += it.next().getIntitule() + ";"; } return "{ " + coursString.substring(0, coursString.length()-1)+ "}"; } public String toString() { return "Etudiant [nom=" + nom + ", niveau=" + niveau + ", cours=" + coursToString() + "]"; } }
Dans la classe Cours
Collection<Etudiant> etudiants = new ArrayList<Etudiant>(); // Attention on ne vérifie pas que l'étudiant n'est pas déjà référencé public void addEtudiant(Etudiant e){ etudiants.add(e); e.addCours(this); } public boolean removeEtudiant(Etudiant e) { boolean retrait = etudiants.remove(e); if (retrait) e.removeCours(this); return retrait; } private String etudiantsToString() { String etudiantsString = " "; Iterator<Etudiant> it = etudiants.iterator(); while (it.hasNext()) { etudiantsString += it.next().toString() + ";"; } return "{ " + etudiantsString.substring(0, etudiantsString.length()-1)+ "}"; } public String toString() { return "Cours [intitule=" + intitule + ", responsable=" + responsable + ", vacataires=" + vacatairesToString() + ", etudiants=" + etudiantsToString() + "]"; }
System.out.println("===================== Etape 4 : Cours-Etudiant ================================="); Etudiant boulard = new Etudiant("Boulard", 0); Etudiant nitchinsky = new Etudiant("Nitchinsky", 0); cBD = new Cours("BD"); System.out.println("Cours [intitule=BD, responsable=null, vacataires={ }, etudiants={ }] \n ==" + cBD); System.out.println("=> Pas de retrait possible (false) = " + cBD.removeEtudiant(boulard)); System.out.println("=> Pas de retrait possible du cours dans etudiant mais pas d erreur " ); System.out.println("Et le cours n'est pas modifié = \n ==" + cBD); cBD.addEtudiant(boulard); System.out.println("=> Ajout pris en compte "); System.out.println("Cours [intitule=BD, responsable=null, vacataires={ }, etudiants={ Etudiant [nom=Boulard, niveau=0, cours={ BD}]}] \n ==" + cBD); System.out.println("=> Pas de retrait possible de nitchinsky(false) = " + cBD.removeEtudiant(nitchinsky)); System.out.println("=> Retrait pris en compte (true) = "+ cBD.removeEtudiant(boulard)); System.out.println("Cours [intitule=BD, responsable=null, vacataires={ }, etudiants={ }]\n ==" + cBD); System.out.println("etudiant ne reference plus le cours :" + boulard); System.out.println("=> Ajouts pris en compte = "); cBD.addEtudiant(boulard); cBD.addEtudiant(nitchinsky); System.out.println("Cours [intitule=BD, responsable=null, vacataires={ }, etudiants={ Etudiant [nom=Boulard, niveau=0, cours={ BD}];Etudiant [nom=Nitchinsky, niveau=0, cours={ BD}]}] \n ==" + cBD); System.out.println("===> un même etudiant dans plusieurs cours "); cProfs = new Cours("Francais"); cProfs.addEtudiant(boulard); System.out.println("Boulars et nitchinsky \n ==" + cBD); System.out.println("Que Boulard \n ==" + cProfs); System.out.println("=> Retrait Boulard pris en compte (true)= "+ cBD.removeEtudiant(boulard)); System.out.println("Que nitchinsky \n ==" + cBD);
public abstract class Control { private String intitule; private double coeff; protected Control(String intitule, double coeff) { super(); this.intitule = intitule; this.coeff = coeff; } public String toString() { return this.getClass().getSimpleName() + " [intitule=" + intitule + ", coeff=" + coeff + "]"; } }
public class DS extends Control { protected DS(String intitule, double coeff) { super(intitule, coeff); } }
public class TD extends Control { protected TD(String intitule, double coeff) { super(intitule, coeff); } }
Dans la classe Cours
/*Constructeur de plus haut niveau * Un cours est automatiquement construit avec un TD et un DS avec des valeurs par défaut * Il faudrait ajouter des méthodes d'accès en lecture comme getTD */ public Cours(String intitule) { this.intitule = intitule; td = new TD("TD_"+ intitule,1); ds = new DS("DS_"+ intitule,1.5); } public String toString() { return "Cours [intitule=" + intitule + ", responsable=" + responsable + ", vacataires=" + vacatairesToString() + ", etudiants=" + etudiantsToString() + td + ds + "]"; }
System.out.println("===================== Etape 5 : Cours-TD/DS ================================="); Cours cBD = new Cours("BD"); System.out.println("=Cours [intitule=BD, responsable=null, vacataires={ }, etudiants={ }TD [intitule=TD_BD, coeff=1.0]DS [intitule=DS_BD, coeff=1.5]] \n ==" + cBD); Professeur prof = new Professeur("Tournesol", "academicien"); cBD = new Cours("BD", prof); System.out.println("Cours [intitule=BD, responsable=Professeur [nom=Tournesol, titre=academicien], vacataires={ }, etudiants={ }TD [intitule=TD_BD, coeff=1.0]DS [intitule=DS_BD, coeff=1.5]]\n ==" + cBD);
Dans les codes la méthode coursAssociée n'a pas été définie ni d'ailleurs dans le modèle. Ici nous avons au niveau des codes orienté la relation. Le modèle devrait être revue pour refléter la réalité des codes.
Dans la figure ci-dessous, nous avons fait le choix de laisser ds visible à la fois comme une association et un attribut pour visualiser la construction interne du DS. Nous aurions pu faire de même pour le TD. Néanmoins, nous déconseillons cette double visualisation d'une même information qui crée de l'ambiguité. L'utilisation de la composition peut donner la même information, mais l'outil la perd lors du passage au code
public class Enseignant { String nom; public Enseignant(String nom) { this.nom = nom; } @Override public String toString() { return "Enseignant : " + nom + " "; } }
public class Description { private int annee; private String section; public Enseignant responsable; public void setResponsable(Enseignant aResponsable) { this.responsable = aResponsable; } public Enseignant getResponsable() { return this.responsable; } protected int getAnnee() { return annee; } protected void setAnnee(int annee) { this.annee = annee; } protected String getSection() { return section; } protected void setSection(String section) { this.section = section; } @Override public String toString() { return "Description [annee=" + annee + ", section=" + section + ", responsable=" + responsable + "]"; } }
public class Module { private int maxDesc = 10; Description[] description = new Description[maxDesc]; private int numberOfDescr = 0; public void addDescription(Description aDescription_d) { if (numberOfDescr==maxDesc) return; else { description[numberOfDescr]=aDescription_d; numberOfDescr++; } } public Enseignant getResponsable(int aAnnee, String aSection) { for (Description d : description) { if ((d!=null) && (d.getAnnee()==aAnnee) && (d.getSection()==aSection)) return d.getResponsable(); } return null; } @Override public String toString() { return "Module [ description=" + Arrays.toString(description) + ", numberOfDescr=" + numberOfDescr + "]"; } }
Module mUML = new Module(); Module mJAVA = new Module(); Description d2014 = new Description(); d2014.setAnnee(2014); d2014.setSection("s2T"); Enseignant E1 = new Enseignant("profTrad"); d2014.setResponsable(E1); mUML.addDescription(d2014); Description e2014 = new Description(); e2014.setAnnee(2014); e2014.setSection("s2A"); Enseignant E2 = new Enseignant("ProfAlt"); e2014.setResponsable(E2); mUML.addDescription(e2014); System.out.println(mUML); System.out.println(mJAVA); System.out.println(mUML.getResponsable(2014, "s2T")); System.out.println(mUML.getResponsable(2014, "s2A")); System.out.println("-----------"); System.out.println("pas de tel cours"); System.out.println(mUML.getResponsable(2015, "s2A")); if (mJAVA.getResponsable(2015, "s2A") == null) System.out.println("pas de tel cours");