This is an old revision of the document!
Table of Contents
Corrections : modélisation et codage
Classe : Code et modélisation
Classe ''TailleHaie''
Un exemple initial de code généré à partir du diagramme ci-après et complété par quelques lignes de code.
package outilsPK; public class TailleHaie { private int _cadence = 4500; public void switchOn() { _cadence = 4500; } public void switchOff() { _cadence = 0; } //Ajoutée pour accéder à la cadence public int get_cadence() { return _cadence; } //non demandée et ne doit pas être accessible private void set_cadence(int cadence) { this._cadence = cadence; } public TailleHaie(){ _cadence = 0; } }
Classe ''Tondeuse''
package outilsPK; public class Tondeuse { private int _cadence = 4500; public void switchOn() { _cadence = 1000; } public void switchOff() { _cadence = 0; } /** * non demandée et ne doit pas être accessible */ private void set_cadence(int aCadence) { throw new UnsupportedOperationException(); } public Tondeuse() { throw new UnsupportedOperationException(); } public int getCadence() { return this._cadence; } }
On remarque alors que l'attribut (variable d'instance) cadence
et la méthode switchOff
sont les mêmes dans les deux classes.
Mise en facteur : OutilElectrique
Voici le code et le modèle en concordance. Il est possible de ne remonter que des méthodes abstraites si vous ne connaissez pas “protected”.
package outilsPK; public abstract class OutilElectrique { private int cadence = 4500; public int get_cadence() { return this.cadence; } public void switchOff() { cadence = 0; } public abstract void switchOn(); protected void setCadence(int cadence){ this.cadence = cadence; } } package outilsPK; public class TailleHaie extends OutilElectrique{ public void switchOn() { this.setCadence(4500); } public TailleHaie(){ this.setCadence(0); } } package outilsPK; public class Tondeuse extends OutilElectrique { public void switchOn() { setCadence(1000); } public Tondeuse() { setCadence(0); } }
Tester
package outilsPK; import static org.junit.Assert.*; import org.junit.Before; import org.junit.Test; public class OutilElectriqueTest { private TailleHaie th; private Tondeuse td; @Before public void setUp() throws Exception { th = new TailleHaie(); td = new Tondeuse(); } @Test public void testSwitchOnTailleHaie() { th.switchOn(); assertEquals(4500, th.getCadence()); } @Test public void testSwitchOnTondeuse() { td.switchOn(); assertEquals(1000, td.getCadence()); } @Test public void testSwitchOff() { th.switchOff();td.switchOff(); assertEquals(0, th.getCadence()); assertEquals(0, td.getCadence()); } @Test public void testSwitchOff_On_Off() { testSwitchOff(); testSwitchOnTondeuse(); testSwitchOnTailleHaie(); testSwitchOff(); } }
Utiliser une classe
Diagramme UML avant génération du code
Puis on génére et compléte la classe jardinier
avec son test
package outilsPK; public class Jardinier { protected OutilElectrique getOutil() { return outil; } protected String getPrenom() { return prenom; } private OutilElectrique outil; private String prenom; /** * * @param outil */ public void startTravail(OutilElectrique outil) { if (this.outil != null) this.outil.switchOff(); this.outil = outil; outil.switchOn(); } public void stopTravail() { outil.switchOff(); outil = null; } @Override public String toString() { return "Jardinier [outil=" + outil + ", prenom=" + prenom + "]"; } public Jardinier(String prenom) { this.prenom = prenom; } }
package outilsPK; import static org.junit.Assert.*; package outilsPK; import static org.junit.Assert.*; import org.junit.Before; import org.junit.Test; public class JardinierTest { private TailleHaie th; private Tondeuse td; private Jardinier j; @Before public void setUp() throws Exception { th = new TailleHaie(); td = new Tondeuse(); j = new Jardinier("Gaston"); } //A revoir car trop de tests en un. @Test public void testJardinerTravaille() { assertEquals(null, j.getOutil()); j.startTravail(th); assertEquals(th, j.getOutil()); // le tailleHaie a été démarré assertEquals(4500, th.getCadence()); j.startTravail(td); // On a bien éteint le tailleHaie assertEquals(0, th.getCadence()); assertEquals(td, j.getOutil()); j.stopTravail(); assertEquals(null, j.getOutil()); assertEquals(0, td.getCadence()); } @Test public void testPrenom() { assertEquals("Gaston", j.getPrenom()); } }
Revoici le diagramme UML après reverse…
Gérer la vitesse : spécialisation de classes et enuméré
On ajoute la vitesse comme un enumerate dans le modèle et les méthodes demandées puis on met à jour les codes.
package outilsPK; public enum Vitesse { arret, lent, moyen, rapide }
package outilsPK; public class Tondeuse extends OutilElectrique { private Vitesse vitesse ; protected Vitesse getVitesse() { return vitesse; } public void switchOn() { setCadence(1000); } public Tondeuse() { setCadence(0); vitesse = Vitesse.arret; } public void setVitesse(Vitesse v){ vitesse = v; } public void switchOff() { super.switchOff(); vitesse = Vitesse.arret; } }
package outilsPK; import static org.junit.Assert.*; import org.junit.Before; import org.junit.Test; public class OutilElectriqueTest { private TailleHaie th; private Tondeuse td; @Before public void setUp() throws Exception { th = new TailleHaie(); td = new Tondeuse(); } @Test public void testSwitchOnTailleHaie() { th.switchOn(); assertEquals(4500, th.getCadence()); } @Test public void testSwitchOnTondeuse() { td.switchOn(); assertEquals(1000, td.getCadence()); } @Test public void testVitesseTondeuse() { td.switchOn(); td.setVitesse(Vitesse.moyen); assertEquals(Vitesse.moyen, td.getVitesse()); td.switchOff(); assertEquals(Vitesse.arret, td.getVitesse()); } @Test public void testSwitchOff() { th.switchOff();td.switchOff(); assertEquals(0, th.getCadence()); assertEquals(0, td.getCadence()); } @Test public void testSwitchOff_On_Off() { testSwitchOff(); testSwitchOnTondeuse(); testSwitchOnTailleHaie(); testSwitchOff(); } }
Reverse et agrégation
Reverse : La classe ''Point''
La classe Chemin
package trajetPK; import java.awt.*; public class Chemin { Point depart; Point arrivee; /** * * @param depart * @param arrivee */ public Chemin(Point depart, Point arrivee) { this.depart = depart; this.arrivee = arrivee; } public double distance() { int y = arrivee.y - depart.y; int x = arrivee.x - depart.x; return Math.sqrt( y*y + x*x); } @Override public String toString() { return "Chemin [depart=" + depart + ", arrivee=" + arrivee + "]"; } }
package trajetPK; import static org.junit.Assert.*; import java.awt.Point; import org.junit.Before; import org.junit.Test; public class CheminTest { private static final double DELTA = 1e-15; Chemin c ; @Before public void setUp() throws Exception { c = new Chemin(new Point(-7,-2), new Point(5,3)); } @Test public void testDistance() { System.out.println(c.distance()); assertEquals(13.0,c.distance(),DELTA); } }
La classe Trajet
package trajetPK; public class MauvaisTrajetException extends Exception { }
package trajetPK; import java.awt.*; public class Chemin { Point depart; Point arrivee; /** * * @param depart * @param arrivee */ public Chemin(Point depart, Point arrivee) { this.depart = depart; this.arrivee = arrivee; } public double distance() { int y = arrivee.y - depart.y; int x = arrivee.x - depart.x; return Math.sqrt( y*y + x*x); } @Override public String toString() { return "Chemin [depart=" + depart + ", arrivee=" + arrivee + "]"; } } <code java> package trajetPK; import java.util.*; public class Trajet { ArrayList<Chemin> chemins; public Trajet(ArrayList<Chemin> chemins) throws MauvaisTrajetException { super(); this.chemins = chemins; Iterator<Chemin> it = chemins.iterator(); if (!(it.hasNext())) throw new MauvaisTrajetException(); Chemin courant = it.next(); Chemin suivant; while (it.hasNext()) { suivant = it.next(); if (courant.arrivee.equals(suivant.depart)) courant = suivant; else throw new MauvaisTrajetException(); } } @Override public String toString() { return "Trajet [chemins=" + chemins + "]"; } }
package trajetPK; import static org.junit.Assert.*; import java.awt.Point; import java.util.ArrayList; import java.util.Arrays; import org.junit.Before; import org.junit.Test; public class TrajetTest { private static final double DELTA = 1e-15; Trajet trValide ; Trajet trUn ; Trajet trInvalide ; Chemin c1 ; Chemin c2 ; Chemin c3; @Before public void setUp() throws Exception { c1 = new Chemin(new Point(-7,-2), new Point(5,3) ); c2 = new Chemin(new Point(5,3), new Point(7,5) ); c3 = new Chemin(new Point(7,5) , new Point(9,11) ); } @Test public void testCreerValide() throws MauvaisTrajetException { trValide = new Trajet ( new ArrayList<Chemin>(Arrays.asList(new Chemin[]{ c1, c2, c3 }))); System.out.println(trValide); } @Test public void testUn() throws MauvaisTrajetException { trUn = new Trajet ( new ArrayList<Chemin>(Arrays.asList(new Chemin[]{ c1}))); } @Test(expected = MauvaisTrajetException.class) public void testInvalide() throws MauvaisTrajetException { trInvalide = new Trajet ( new ArrayList<Chemin>(Arrays.asList(new Chemin[]{ c1, c3 }))); }
La classe ''Polygone''
Un polygone est composé d'un ensemble de points.
package geometrie; import java.util.ArrayList; import java.util.Arrays; import java.awt.Point; public class Polygone { public ArrayList<Point> _points = new ArrayList<Point>(); public Polygone() { } public Polygone(Point[] points) { _points = new ArrayList<Point>(Arrays.asList(points)); } @Override public String toString() { String pointsAsString =" "; for(Point p : _points) pointsAsString += p + " ; "; return "Polygone [_points=" + pointsAsString + "]"; } /** * * @param p */ public void addPoint(Point p) { _points.add(p); } }
La classe ''Polygone'': V2
- Pour remplir le tableau de points, on a besoin d'une première méthode
addPoint
qui ajoutera un
point à ceux déjà présents.
- Etendez votre modélisation de la classe
Polygone
en UML. - Générer le code. Quelle structure de données utilisez vous? Regarder le code généré …
- Tester votre classe.
- Que retenez-vous de cet exercice? Quand se fait le choix de la structure?