====== Des modèles aux codes et vis-versa ====== **Objectifs :** - Faire un lien direct entre la modélisation des classes et les codes correspondants. Nous faisons le lien entre modeles et codes. Vous pouvez travailler les codes uniquement au niveau du papier. Vous devez essentiellement comprendre les grands principes. L'utilisation d'un outil pour coder n'est pas indispensable dans ce TD. Si vous le voulez vous pouvez utiliser ECLIPSE, mais la version NEON3, les autres ne fonctionnent pas... ===== Je comprends ===== ==== Je sais passer du dessin d'une classe au code ==== {{:2017_2018:s2:td:outrider.jpg?300 |}} {{:2017_2018:s2:td:engin.png?200|}} Le concept d'"Engin" modélisé ici sous la forme d'une classe sera représenté par le code suivant : ** En Java** public class Engine { } ** En C#** public class Engine { }; ** En PHP** Une "instance" du concept d'engin sera par exemple "Defiance", un vaisseau spacial. On crée une instance d'engin en java par le code suivant : Engine defiance = new Engine(); On crée un autre engin par : Engine xwing = new Engine(); ==== Je sais passer du dessin d'une classe avec un attribut au code ==== {{:2017_2018:s2:td:engine-1attr.png?200|}} Le concept d'"Engin" modélisé ici sous la forme d'une classe contient à présent un attribut qui permet d'exprimer la puissance. Il sera représenté par le code suivant : ** Code généré en Java** public class Engine { private int power; } ** Code généré en C#** public class Engine { private int power; } **Code généré en php** === Complétons ce code === Pour pouvoir accéder à cet attribut nous allons à présent dans le code définir des //accesseurs//. Le code de la classe Engin en java devient : public class Engine { private int power; //Accesseur en lecture : on lit la valeur de l'attribut power public int getPower() { return power; } //Accesseur en écriture : on modifie la valeur de l'attribut power (noté this.power) avec la valeur en parametre power public void setPower(int power) { this.power = power; } } A partir de ce code, nous pouvons à présent créer une "instance" de la classe "Engine" et lui affecter une puissance de 2000. public class TestInMain { public static void main(String[] args) { Engine defiance = new Engine(); //Set Power to 2000 defiance.setPower(2000); //Get power of defiance int defiancePower = defiance.getPower(); //Print Defiance's power System.out.println("Power : " + defiancePower); } } Représentation d'une instance de la classe ''Engine'' {{:2017_2018:s2:td:instance.png?200|}} ==== Je sais passer du dessin d'une classe avec un attribut et une méthode au code ==== {{:2017_2018:s2:td:engine-stop.png?200|}} **Code généré en java** public class Engine { private int power; public void stop() { throw new UnsupportedOperationException(); } } **Code généré en php** Une proposition d'implémentation en java pour ''stop'' : public class Engine { private int power; public void stop() { power = 0; } } **Utilisation de la méthode Stop ** public class TestInMain { public static void main(String[] args) { Engine defiance = new Engine(); //Set Power to 2000 defiance.setPower(2000); //Get power of defiance int defiancePower = defiance.getPower(); //Print Defiance's power : expected 2000 System.out.println("Power : " + defiancePower); //Stop the engine defiance defiance.stop(); //Get power of defiance defiancePower = defiance.getPower(); //Print Defiance's power : expected 0 System.out.println("Power : " + defiancePower); } } ==== Je sais passer du dessin d'une association au code ==== {{:2017_2018:s2:td:14450576294_886eb4b940_b.jpg?300 |}} {{:2017_2018:s2:td:capture_d_e_cran_2018-02-11_a_01.14.10.png?500|}} **Code java correspondant ** public class Engine { private int power; //Association becomes an attribute ; multiplicity * => array or any collections private Pilot[] pilots; // = new Pilot[0]; //array de dimension 1 public int getPower() { return power; } public void setPower(int power) { this.power = power; } public void stop() { power = 0; } } et une nouvelle classe : public class Pilot { } Complétons la classe ''Engine'' pour manipuler les pilotes. public class Engine { private int power; private Pilot[] pilots = new Pilot[1]; public Pilot[] getPilots() { return pilots; } public void setPilots(Pilot[] pilots) { this.pilots = pilots; } public void addPilotAtRank(Pilot onePilot, int rank) { if (rank < pilots.length & rank >=0 ) this.pilots[rank] = onePilot; //else //too many pilots, do nothing } public int getPower() { return power; } public void setPower(int power) { this.power = power; } public void stop() { power = 0; } } Utilisons notre nouveau code en complétant le main //Admiral Nammo Pilot nammo = new Pilot(); defiance.addPilotAtRank(nammo, 0); //Get the pilots of defiance Pilot[] ourPilots = defiance.getPilots(); //Print the first pilot (only object reference) System.out.println("Pilot : " + ourPilots[0]); } ==== Relation Bidirectionnelle ==== {{:2017_2018:s2:td:abf17ef0.png?500|}} On peut naviguer à présent du pilote à l'engin et inversement. La classe ''Pilot'' générée est donc modifiée. Remarquez que la mulitplicité de 1 cette fois-ci crée un attribut simple de type Engine public class Pilot { private Engine drivenEngine; } Nous complétons le code pour pouvoir accéder et modifier le moteur associé au pilot. public class Pilot { private Engine drivenEngine; public Engine getDrivenEngine() { return drivenEngine; } public void setDrivenEngine(Engine newEngine) { this.drivenEngine = newEngine; } } Pour tester nous ajoutons à présent l'engin defiance comme celui conduit par l'amiral //nammo// nammo.setDrivenEngine(defiance); Nous décidons à présent que l'on ne veut pas que n'importe qui affecte un engin à un pilote (on passe la méthode setDrivenEngine en Protected) et que lorsque l'on affecte un pilote à un engin alors il en devient pilote. Nous modifions nos codes comme suit. package tdS2; public class Engine { private int power; private Pilot[] pilots = new Pilot[1]; public Pilot[] getPilots() { return pilots; } public void setPilots(Pilot[] pilots) { this.pilots = pilots; } public void addPilotAtRank(Pilot onePilot, int rank) { if (rank < pilots.length & rank >=0 ) this.pilots[rank] = onePilot; onePilot.setDrivenEngine(this); //else //too many pilots, do nothing } public int getPower() { return power; } public void setPower(int power) { this.power = power; } public void stop() { power = 0; } } public class Pilot { private Engine drivenEngine; public Engine getDrivenEngine() { return drivenEngine; } protected void setDrivenEngine(Engine newEngine) { this.drivenEngine = newEngine; } } Nous utilisons ce code. Engine X100rocketBoosters = new Engine(); Pilot r2D2 = new Pilot(); X100rocketBoosters.addPilotAtRank(r2D2, 0); //expected one pilot pilots = X100rocketBoosters.getPilots(); System.out.println("expected one pilot" + pilots); Engine engine4R2D2 = r2D2.getDrivenEngine(); System.out.println("expected one engine" + engine4R2D2); ===== A vous ===== {{:2017_2018:s2:td:capture_d_e_cran_2018-01-21_a_23.23.59.png?200|}} - Quel code correspond au diagramme de classe UML ci dessus ? (( private Position position = new Position(); )) - La méthode move correspond à modifier la position.(( public void move (int x, int y) { position.setX(x); position.setY(y); } )) - Compléter le diagramme pour ajouter un nom au pilote. === ET aussi : === {{:2017_2018:s2:td:association-engin.png?200|}} - Quel code correspond au diagramme de classe UML ci dessus (A faire en complétant les diagrammes précédents)? /* === et encore === {{:2017_2018:s2:td:armada.png?200|{{:2017_2018:s2:td:association-engin.png?200|}}}} - Quel code correspond au diagramme de classe UML ci dessus ? */ ===== Je sais passer du dessin d'une relation d'héritage au code ==== {{:2017_2018:s2:td:star-wars-the-old-republic-girl-warrior-lightsabers-battle-smoke-wallpaper-hd.jpg?300 |}} {{:2017_2018:s2:td:weapons.png?400|}} **Classe Weapon** public class Weapon { private Jedi belongsTo ; public Jedi getBelongsTo() { return belongsTo; } public void setBelongsTo(Jedi owner) { this.belongsTo = owner; } } **Classe MeleeWeapon "hérite de"/"Spécialise" Weapon** public class MeleeWeapon extends Weapon{ } **Classe Lightsaber "hérite de"/"Spécialise" MeleeWeapon** public class Lightsaber extends MeleeWeapon{ } Je peux accéder au propriétaire d'une arme quelconque. Lightsaber excaLight = new Lightsaber(); Jedi Revan = new Jedi(); excaLight.setBelongsTo(Revan); ===== A vous ==== /* {{:2017_2018:s2:td:heritage_2018-01-21_a_23.43.58.png?300|}} */ {{:2017_2018:s2:td:star-wars-armada-2400x1200-259395126765.jpg?300 |}} {{:2017_2018:s2:td:spacialship.png?700|}} - Quel code correspond au diagramme de classe UML ci dessus ? - Imaginez que l'on veuille pouvoir demander à une ''Armada'' d'attaquer, quelle méthode devez-vous ajouter? - Voici le code de cette nouvelle méthode : public void attack() { //All engines must attack for (Engine e : engines) //e is one Engine in engines e.attack(); } - Voici un code qui peut permettre de créer une ''Armada'', de lui associer 10 ''Engine'' et de déclencher une attaque Armada sithArmada = new Armada(); //Array of 10 Engines Engine[] machines = new Engine[10]; //Initialise with 10 Engine for(int i=0; i<10; i++){ machines[i] = new Engine(); } sithArmada.setEngines(machines); sithArmada.attack(); ===== Je sais passer du code au modèle ===== public class Avatar { private String name; private Position pos; private Weapon[] weapons; public Position moveDelta(int x, int y) { pos.addX(x); pos.addY(y); return pos; } } public class Submarine extends Engine{ private int capacity; private DecompressionChamber decompressionChamber; } - Quel modèle correspond au code ci-dessus ? ====== Diagrammes de séquence, diagramme de classe et Codes ====== ===== Du diagramme de séquence au diagramme de classes ===== {{ :2017_2018:s2:td:darth-vader-stormtroopers-wide-wallpaper.jpg?300 |}} Voici un diagramme de séquence, complétez le diagramme de classe pour tenir compte des nouveaux éléments. {{:2017_2018:s2:td:sequence.png?600|}} Pour vous aider : * Quelles sont les nouvelles classes? * Quelles sont les associations entre ces classes ? * Quelles sont les méthodes portées par ces classes? ===== Complétez le diagramme de séquence ===== Compléter les deux diagrammes pour introduire : - les armadas attaquent. Chaque armada demande à ses engins d'attaquer. ===== Du diagramme de séquence aux codes ===== - Construire vos classes au niveau du code - Complétez vos codes pour prendre en compte le diagramme de séquence