COURS 3 : Programmation impérative Cours Java (I21) - Licence 1 Semestre 2 / Y.Laborde 26/03/2017 COURS 3 : Programmation impérative Classes et objets simples Découpage structurel et fonctionnel Modularité fonctionnelle, robustesse et maintenance Classes et objets simples sans méthode Méthodes d’instance simples Plus à propos de Java Résumé du cours précédent Cours JAVA (I21) -Licence 1 Semestre 2 / Y.Laborde
Classes&objets : Comment this est-il mis à jour ? Cours Java (I21) - Licence 1 Semestre 2 / Y.Laborde 26/03/2017 Classes&objets : Comment this est-il mis à jour ? classe MainDominos +$ main(String[]) { test1(); } +$ test1() { Domino d4 = new Domino(3,4); if ( ) { // faire quelque chose... } classe Domino m1 : int m2 : int +Domino(int,int) +Domino(int) +Domino() this.m1 this.m2 public boolean estDouble(){ } d4.estDouble() return ( == ); invocation de la méthode exécution de la méthode Maintenant « this » réfère à d4 mise à jour de « this » ① Le fait d’utiliser d4 comme base d’invocation de la méthode estDouble() a pour effet de lier la méthode à l’objet référé par d4 ; ② C’est à ce moment que Java met à jour la variable this ! (i.e. « this » prend la valeur de « d4 ») ③ Et ce n’est qu’ensuite que Java exécute la méthode dans sa classe propre. Cours JAVA (I21) -Licence 1 Semestre 2 / Y.Laborde
Classes&objets: CONSTRUCTEURS, VARIABLES et METHODES D’INSTANCE Cours Java (I21) - Licence 1 Semestre 2 / Y.Laborde 26/03/2017 Classes&objets: CONSTRUCTEURS, VARIABLES et METHODES D’INSTANCE Classes & Objets = VARIABLES D’INSTANCES (=ATTRIBUTS) + CONSTRUCTEURS + METHODES D’INSTANCES classe Domino m1 : int m2 : int +Domino(int,int) +Domino(int) +Domino() VARIABLES D’INSTANCE ATTRIBUTS ou ETAT C’est de cette manière que les objets et leurs classes doivent être conçus dans le paradigme Orienté-Objet. CONSTRUCTEURS METHODES D’INSTANCE +dominoToString(): String +estDouble(): boolean +valeur() : int +plusGrandQue(Domino d) : int +plusGrandeMarque() : int En Orienté-Objet, un objet est vu comme une entité qui encapsule un état interne (ensemble des valeurs des var. d’inst.) et qui fournit des services (méth. d’inst.) par rapport à cet état. Cours JAVA (I21) -Licence 1 Semestre 2 / Y.Laborde
Classes&objets: CONSTRUCTEURS, VARIABLES et METHODES D’INSTANCE Cours Java (I21) - Licence 1 Semestre 2 / Y.Laborde 26/03/2017 Classes&objets: CONSTRUCTEURS, VARIABLES et METHODES D’INSTANCE classe MainDominos et classe MainBooks +$main(String[]): void +$test1(): void +$test2(): void Classes des cours et TD revisitées : classe Domino m1 : int m2 : int +Domino(int,int) +Domino(int) +Domino() +dominoToString(): String +estDouble(): boolean +valeur(): int +plusGrandQue(Domino d): int +plusGrandeMarque(): int classe ISBN (anglicisée) groupA : int groupB : int groupC : String groupD : String +ISBN(int,int,String,String) classe Book (anglicisée) title : String autor : String editor : String nbPages : int isbn : ISBN +Book(String,String,String,int,ISBN) +bookToString(): String +hasAutor(String firstname, String lastname): boolean +isFrancophone(): boolean +isEditedBy (String): boolean +isEditedBy(int): boolean +isbnToString(): String +isFrancophone(): boolean +isEditedBy (int): boolean Cours JAVA (I21) -Licence 1 Semestre 2 / Y.Laborde FIRST NAME : prénom / LAST NAME : nom de famille / MIDDLE NAMES : autres prénoms
Objectifs de ce cours (I21) Classes et objets simples Découpage structurel et fonctionnel Modularité fonctionnelle, robustesse et maintenance Classes et objets simples sans méthode Méthodes d’instance simples Plus à propos de Java Classes et Objets ensemblistes Maintenant ! Cours JAVA (I21) -Licence 1 Semestre 2 / Y.Laborde
Classes&objets : VÉRITABLES ENTITÉS AUTONOMES* Cours Java (I21) - Licence 1 Semestre 2 / Y.Laborde 26/03/2017 Classes&objets : VÉRITABLES ENTITÉS AUTONOMES* ➽ Le paradigme Orienté-Objet a permis : d’inclure dans les objets des méthodes d’instance « responsables » d’agir sur leurs attributs ➽ Nos objets sont maintenant à la fois des structures de données (attributs valués/var. d’inst./état) et des fournisseurs de fonctionnalités (méthodes d’instance) ➽ Au final, les objets apparaissent donc comme de véritables entités dotées d’une certaine* autonomie. Expliquer le terme « certaine autonomie » en montrant que les objets peuvent aussi dépendre les uns des autres. Ré-expliquer le mot « responsable » en montrant qu’il inclus de nombreuses facettes : en capacité de dont le rôle est de qui assure que l’usage qui est fait des attributs reste toujours correct * autonomie à relativiser car les objets peuvent aussi dépendre les uns des autres (ex: un livre et son ISBN) Cours JAVA (I21) -Licence 1 Semestre 2 / Y.Laborde
Classes&objets : le problème des ENSEMBLES d’OBJETS Cours Java (I21) - Licence 1 Semestre 2 / Y.Laborde 26/03/2017 Classes&objets : le problème des ENSEMBLES d’OBJETS Mais les problèmes réels manipulent – le plus souvent – de nombreuses données d’un même type : un jeu de dominos un stock de livres Il devient donc nécessaire de disposer de classes permettant de traiter des ensembles d’objets d’un même type : nous les appellerons des classes ensemblistes Ici, nous allons voir deux manières de traiter les ensembles d’objets : ➽ COMMENT LES TRAITER à l’aide de TABLEAUX ➽ COMMENT LES TRAITER à l’aide de CLASSES génériques à Spécialiser Cours JAVA (I21) -Licence 1 Semestre 2 / Y.Laborde
COMMENT AVONS-NOUS TRAITÉ LES ENSEMBLES D’OBJETS JUSQUE LÀ ? Cours Java (I21) - Licence 1 Semestre 2 / Y.Laborde 26/03/2017 COMMENT AVONS-NOUS TRAITÉ LES ENSEMBLES D’OBJETS JUSQUE LÀ ? Le simple fait d’utiliser des tableaux d’objets n’est pas satisfaisant en Orienté-Objet car on ne peut leurs associer aucune méthode d’instance. Tout juste possèdent-t-ils une variable d’instance length (constante). AGIT SUR LE TABLEAU DE DOMINOS => méthode d’instance IMPOSSIBLE ici Exemple : classe MainDominos +$ main(String[]) { test1(); } +$ test1() { Domino[] miniJeu = { new Domino(0,0), new Domino(0,1), new Domino(0,2) }; System.out.println( "Jeu contenant " + miniJeu.length + " dominos"); System.out.println(setDominosToString(miniJeu)); } +$ setDominosToString(Domino[] setDominos) { String s = ""; for( Domino d : setDominos ) { s += d.dominoToString(); return s; En l’absence de classe pour recevoir le tableau d’objets, le paradigme de l’O-O ne s’applique pas au tableau. Celui-ci reste un objet simpliste (une simple structure de donnée) puisqu’il est privé de méthode d’instance. OBJET SIMPLISTE = objet sans méthode d’instance (comme on faisait au début) On ne peut pas écrire miniJeu.setDominosToString() ! Ce qui correspond à déporter vers le tableau la connaissance permettant de traiter la fonctionnalité voulue et NON DE LA LAISSER A CELUI QUI INSTANCIE UN TABLEAU N’AGIT QUE SUR UN SEUL DOMINO => méthode d’instance de la classe Domino Cours JAVA (I21) -Licence 1 Semestre 2 / Y.Laborde
(A) CLASSE ENCAPSULANT UN TABLEAU D’OBJETS Cours Java (I21) - Licence 1 Semestre 2 / Y.Laborde 26/03/2017 (A) CLASSE ENCAPSULANT UN TABLEAU D’OBJETS ➽ Créer une classe spécifique pour contenir un ensemble de dominos sous la forme d’un tableau. Ici, class JeuDominos par exemple Solution : classe JeuDominos ➽ Encapsuler le tableau de dominos dans la classe comme variable d’instance. Ici, Domino[] jeu Domino[] jeu; // le jeu de dominos // méthode d’instance +String jeuDominosToString() { String s = ""; for( Domino d : this.jeu) { s += d.dominoToString(); } return s; ➽ Doter la classe des méthodes d’instance utiles. Ici, public String jeuDominosToString() En même temps, la classe JeuDominos se justifie par le fait qu’il faille prévoir une classe pour être en mesure de jouer aux dominos. Cette classe pourra contenir bien d’autres choses que le simple jeu. Exemples: la pioche, les joueurs, la ligne de jeu... +JeuDominos() // le constructeur Le tableau de dominos étant une variable d’instance, l’accès se fait à l’aide de this ➽ Il reste à prévoir comment le jeu de dominos pourra être construit. Cours JAVA (I21) -Licence 1 Semestre 2 / Y.Laborde
(A) CLASSE ENCAPSULANT UN TABLEAU D’OBJETS Cours Java (I21) - Licence 1 Semestre 2 / Y.Laborde 26/03/2017 (A) CLASSE ENCAPSULANT UN TABLEAU D’OBJETS Plusieurs solutions sont envisageables mais ici on préfèrera procéder ainsi : Solution : classe JeuDominos jeu:Domino[] // le tableau de dominos ➽ Construire un jeu de dominos vide pour commencer // Constructeur d’un jeu vide public JeuDominos() { this.jeu = new Domino[0]; } Tableau vide (ZERO éléments) // Méthodes d’instance qui crée un jeu public void createJeuNormal(){ this.jeu = new Domino[28](); int n = 0; for( int m1=0 ; m1<=6 ; m1++) for( int m2=i ; m2<=6 ; m2++) // Placer un nouveau domino de // marque m1,m2 à la position n this.jeu[n++] = new Domino(m1,m2); } +jeuDominosToString():String ➽ Ajouter une méthode d’instance qui crée un un jeu de dominos. Ex: public void createJeuNormal() Ecrire au tableau une solution correspondant à this.jeu = null; et qui ne provoque pas de pb dans jeuDominosToString() : public String jeuDominosToString() { String s = ""; if ( this.jeu != null ) { for( Domino d : this.jeu) { s += d.dominoToString(); } return s; On aurait aussi pu vouloir écrire : this.jeu = null; mais la méthode jeuDominosToString() n’aurait pas fonctionnée correctement dans le cas où le jeu n’aurait pas encore été créé. Cours JAVA (I21) -Licence 1 Semestre 2 / Y.Laborde
(A) CLASSE ENCAPSULANT UN TABLEAU D’OBJETS Cours Java (I21) - Licence 1 Semestre 2 / Y.Laborde 26/03/2017 (A) CLASSE ENCAPSULANT UN TABLEAU D’OBJETS Pour donner la possibilité de connaître facilement le nombre de dominos du jeu, on peut ajouter une nouvelle méthode d’instance. Complément : Cela permet d’éviter d’avoir à accéder au tableau de dominos depuis l’extérieur de cette classe, en faisant : <unJeuDeDomino>.jeu.length classe JeuDominos // le tableau de dominos jeu:Domino[] // Méthodes d’instance +createJeuNormal():void +jeuDominosToString():String // Méthodes d’instance qui fournit // le nombre actuel de dominos du jeu public int size(){ return this.jeu.length; } // Constructeur d’un jeu vide +JeuDominos() ➽ Ajouter une méthode d’instance qui fournit le nombre de dominos du jeu. Ex: public int size() En même temps, la classe JeuDominos se justifie par le fait qu’il faille prévoir une classe pour être en mesure de jouer aux dominos. Cette classe pourra contenir bien d’autres choses que le simple jeu. Exemples: la pioche, les joueurs, la ligne de jeu... ➽ Il ne reste qu’à utiliser cette classe dans un applicatif. Cours JAVA (I21) -Licence 1 Semestre 2 / Y.Laborde
(A) CLASSE ENCAPSULANT UN TABLEAU D’OBJETS Cours Java (I21) - Licence 1 Semestre 2 / Y.Laborde 26/03/2017 (A) CLASSE ENCAPSULANT UN TABLEAU D’OBJETS classe JeuDominos // Variable d’instance jeu:Domino[] // Méthodes d’instance +createJeuNormal():void +jeuDominosToString():String +size():int // Constructeur d’un jeu vide +JeuDominos() Applicatif : On veut construire puis afficher un jeu de dominos ① Créer un jeu de dominos vide ② Ajouter des dominos au jeu ③ Afficher le nombre de dominos du jeu ④ Afficher tous les dominos du jeu Au final, on s’aperçoit que la classe MainDominos n’a plus besoin d’accéder directement au tableau de dominos (qui se trouve maintenant dans le jeu) classe MainDominos +$ main(String[]) { test1(); } +$ test1() { } ➽ En même temps, la classe JeuDominos se justifie par le fait qu’il faille prévoir une classe pour être en mesure de jouer aux dominos. Cette classe pourra contenir bien d’autres choses que le simple jeu. Exemples: la pioche, les joueurs, la ligne de jeu... ① JeuDominos jeuNormal = new JeuDominos(); ② jeuNormal.createJeuNormal(); ③ System.out.println( "Jeu contenant " + jeuNormal.size() + " dominos"); Ceci constitue une bonne pratique dans le paradigme Orienté-Objet ! ④ System.out.println(jeuNormal.jeuDominosToString()); Utilisations des méthodes d’instance de la classe JeuDominos Cours JAVA (I21) -Licence 1 Semestre 2 / Y.Laborde
OBJECTIFS DU PARADIGME ORIENTÉ-OBJET Cours Java (I21) - Licence 1 Semestre 2 / Y.Laborde 26/03/2017 OBJECTIFS DU PARADIGME ORIENTÉ-OBJET Ce que nous venons de mettre en œuvre est en parfait accord avec l’objectif du paradigme Orienté-Objet : Un problème étant posé : ➽ le décomposer en plusieurs petites entités plus simples (classes) : => faire apparaître des classes d’objets bien ciblées >>> leurs donner le maximum d’autonomie (en évitant qu’elles délèguent à d’autres ce qu’elles peuvent faire) >>> leurs permettre d’être manipulées extérieurement le plus facilement possible (en les dotant de méthodes d’instance utiles à la résolution globale) ➽ résoudre le problème global posé en faisant interagir ces entités entre elles : => ici, il ne s’agit plus que de manipuler les entités depuis l’extérieur Cours JAVA (I21) -Licence 1 Semestre 2 / Y.Laborde
(A) CLASSE ENCAPSULANT UN TABLEAU D’OBJETS Cours Java (I21) - Licence 1 Semestre 2 / Y.Laborde 26/03/2017 (A) CLASSE ENCAPSULANT UN TABLEAU D’OBJETS Quel est le champ d’utilisation des classes encapsulant des tableaux ? Dans l’exemple traité (un jeu de dominos), nous n’avons fait que construire un jeu de dominos. Mais pour jouer aux dominos, il faudrait penser à : la création de la pioche la distribution de dominos aux joueurs la constitution de la ligne de jeu UN JEU EN COURS Ce qui revient à partager le jeu initial en sous-ensembles de dominos de tailles variables la pioche (taille décroissante) la donne des joueurs (taille variable) la ligne de jeu (taille croissante) -3 +3 -1 +1 Cours JAVA (I21) -Licence 1 Semestre 2 / Y.Laborde
(A) CLASSE ENCAPSULANT UN TABLEAU D’OBJETS Cours Java (I21) - Licence 1 Semestre 2 / Y.Laborde 26/03/2017 (A) CLASSE ENCAPSULANT UN TABLEAU D’OBJETS Lorsque la taille des ensembles d’objets est variable, cela induit un ASPECT DYNAMIQUE. Cet aspect dynamique complique la gestion des tableaux car ceux-ci sont des STRUCTURES DE DONNÉES STATIQUES. ➽ les classes encapsulant des ensembles d’objets de taille variable ont donc pour travail de rendre dynamique une structure de donnée normalement statique. ➽ La ligne de jeu gagne 1 domino ligneDeJeu = new Domino[4+1] ➽ La pioche perd 3 dominos pioche = new Domino[14-3] ➽ La donne contient 2 dominos de plus donne = new Domino[4+3-1] Cours JAVA (I21) -Licence 1 Semestre 2 / Y.Laborde
(A) CLASSE ENCAPSULANT UN TABLEAU D’OBJETS Cours Java (I21) - Licence 1 Semestre 2 / Y.Laborde 26/03/2017 (A) CLASSE ENCAPSULANT UN TABLEAU D’OBJETS De quelles méthodes faudrait-il disposer pour que les classes qui encapsulent des ensembles d’objets variables soient facilement utilisables de l’extérieur ? L’exemple de la pioche ① Pouvoir créer une pioche vide (constructeur) classe Pioche // Variable d’instance laPioche:Domino[] // Méthodes d’instance +piocheToString():String // Constructeur de pioche vide ② Pouvoir ajouter un domino à la pioche ③ Pouvoir ajouter plusieurs dominos en une fois ④ Pouvoir tester si la pioche est vide ① +Pioche() ⑤ Pouvoir connaître le nombre de dominos de la pioche ⑥ Pouvoir piocher un domino aléatoirement +add(Domino d):void ② ③ +add(Domino[] setDominos):void Ecrire les méthodes d’instance SUR LA BASE d’un CONSTRUCTEUR qui fait this.laPioche = null; ④ +isEmpty():boolean ➽ Il ne reste qu’à écrire ces méthodes d’instance On se basera sur un constructeur qui initialise la variable d’instance à null (fait pendant le cours) ⑤ +size():int ⑥ +piocheUnDomino():Domino Cours JAVA (I21) -Licence 1 Semestre 2 / Y.Laborde
(A) CLASSE ENCAPSULANT UN TABLEAU D’OBJETS Cours Java (I21) - Licence 1 Semestre 2 / Y.Laborde 26/03/2017 (A) CLASSE ENCAPSULANT UN TABLEAU D’OBJETS ① Pouvoir créer une donne vide (constructeur) L’exemple de la donne des joueurs ② Pouvoir ajouter un domino à la donne C’est le jeu de dominos qui pourrait distribuer les dominos aux joueurs classe DonneJoueur // Variable d’instance laDonne:Domino[] // Méthodes d’instance +donneToString():String // Constructeur de donne vide ③ Pouvoir ajouter plusieurs dominos en une fois Idem mais en fournissant tous les dominos d’un coup (par exemple) ④ Pouvoir tester si la donne est vide Ce peut être utile pour savoir si le joueur a gagné (le jeu doit terminer) ① +DonneJoueur() ⑤ Pouvoir connaître le nombre de dominos de la donne ⑥ Pouvoir extraire un domino choisi par son rang Ce peut être utile pour permettre au joueur de jouer un certain domino +add(Domino d):void ② ⑦ Pouvoir extraire un domino choisi par sa référence Idem mais en désignant le domino par sa référence d’objet ③ +add(Domino[] setDominos):void ④ +isEmpty():boolean ⑧ Pouvoir faire jouer le joueur sur la base d’une pioche et d’une ligne de jeu Cette méthode permettrait à un joueur de « demander » à sa donne de jouer un domino relativement à une pioche et une ligne de jeu ⑤ +size():int ⑥ +extractDomino(int rg):Domino ⑦ +extractDomino(Domino d):Domino ⑧ +joueUnDomino(Pioche pioche, LigneDeJeu ldj):boolean ⑨ Pouvoir retrouver le plus grand domino jouable Cette méthode permettrait d’adopter une stratégie de jeu qui tente de jouer le plus gros domino de la donne compte tenu d’une ligne de jeu ⑨ +getDominoMaxValueToPlay(LigneDeJeu ldj):Domino ⑩ Etc. ⑩ ... Cours JAVA (I21) -Licence 1 Semestre 2 / Y.Laborde
(A) CLASSE ENCAPSULANT UN TABLEAU D’OBJETS Cours Java (I21) - Licence 1 Semestre 2 / Y.Laborde 26/03/2017 (A) CLASSE ENCAPSULANT UN TABLEAU D’OBJETS ① Pouvoir créer une ligne de jeu vide (constructeur) L’exemple de la ligne de jeu ② Pouvoir ajouter un domino à droite de la ligne de jeu Permet aux joueurs d’ajouter un domino à droite d’une la ligne de jeu classe LigneDeJeu // Variable d’instance ldj:Domino[] // Méthodes d’instance +donneToString():String // Constructeur de donne vide ③ Pouvoir ajouter un domino à gauche de la ligne Idem mais à gauche ④ Pouvoir tester si la ligne de jeu est vide Ce peut être utile pour savoir si on doit jouer un double (début de jeu) ① +DonneJoueur() ⑤ Pouvoir connaître le nombre de dominos de la donne ⑥ Pouvoir connaître un domino choisi par son rang Peut être utile pour permettre au joueur d’adopter une stratégie de jeu +addToRight(Domino d):boolean ② ⑦ Pouvoir connaître un domino choisi par sa référence Idem mais en désignant le domino par sa référence d’objet ③ +addToLeft(Domino d):boolean ④ +isEmpty():boolean ⑧ Savoir si un domino est jouable à droite de la ligne de jeu Permettrait à un joueur de « demander » à la ligne de jeu si un certain domino peut y être accolé à droite ⑤ +size():int ⑥ +getDomino(int rg):Domino ⑦ +getDomino(Domino d):Domino ⑧ +isAccolableToRight(Domino d):boolean ⑨ Savoir si un domino est jouable à droite de la ligne de jeu Idem mais à gauche ⑨ +isAccolableToLeft(Domino d):boolean ⑩ ... ⑩ etc. Cours JAVA (I21) -Licence 1 Semestre 2 / Y.Laborde
(A) CLASSE ENCAPSULANT UN TABLEAU D’OBJETS Cours Java (I21) - Licence 1 Semestre 2 / Y.Laborde 26/03/2017 (A) CLASSE ENCAPSULANT UN TABLEAU D’OBJETS A travers ces exemples, on voit apparaître des classes dotées de méthodes d’instance dont le rôle est de fournir des fonctionnalités utiles aux objets qui les instancient. Les trois classes ensemblistes (Pioche, Donne et LigneDeJeu) doivent interagir car elles participent à un même objectif de jeu. Chacune représente une part du programme de jeu de dominos. A la base, la classe JeuDominos devrait instancier une pioche , une ligne de jeu et des joueurs, eux-mêmes instanciant leur propre donne. Finalement, la classe JeuDominos jouent le rôle de chef d’orchestre pour l’application. Au départ, c’est d’elle que (1) le jeu sera construit puis que (2) le jeu se déroulera en délégant aux autres objets la plupart des fonctionnalités du jeu : 1 objet JeuDominos 1 objet LigneDeJeu contient 1 objet Pioche 1 objet Joueur 1 objet Donne 1 table de Joueurs contient contient Cours JAVA (I21) -Licence 1 Semestre 2 / Y.Laborde
(A) CLASSE ENCAPSULANT UN TABLEAU D’OBJETS Cours Java (I21) - Licence 1 Semestre 2 / Y.Laborde 26/03/2017 (A) CLASSE ENCAPSULANT UN TABLEAU D’OBJETS On voit ici tout l’intérêt du premier concept de l’Orienté-Objet : Les objets encapsulent des données et des méthodes agissant sur leurs données ➽A partir de là, il est possible de déléguer les fonctionnalités aux objets qui savent le mieux les réaliser. délégation 1 objet Donne 1 objet JeuDominos 1 objet LigneDeJeu 1 objet Pioche 1 table de Joueurs 1 objet Joueur retours contient ➽ Faire jouer les joueurs à tour de rôle (simple boucle qui délègue aux joueurs le fait de jouer en leur donnant une pioche et une ligne de jeu) délégation délégation ➽ Rechercher le meilleur coup (en utilisant la pioche, la ligne de jeu et en utilisant une stratégie éventuel-lement définie par le joueur) ➽ Faire jouer ce joueur (en donnant une pioche et une ligne de jeu) JeuDominos DELEGUE à Joueur le fait de jouer un coup Joueur DELEGUE à Donne le fait de rechercher le meilleur coup Donne DELEGUE à Pioche le fait de piocher Donne DELEGUE à LigneDeJeu le fait de tester si un domino est jouable retour retour Pour que le jeu se déroule, c’est de la classe JeuDominos qu’une méthode d’instance devra faire jouer les joueurs à tour de rôle jusqu’à la fin de la partie. Mais le fait de jouer un coup sera délégué à chaque joueur. Et enfin, la délégation se poursuit vers la donne, la pioche et la ligne de jeu. Cours JAVA (I21) -Licence 1 Semestre 2 / Y.Laborde
PROTECTION DE L’ÉTAT INTERNE DES OBJETS Cours Java (I21) - Licence 1 Semestre 2 / Y.Laborde 26/03/2017 PROTECTION DE L’ÉTAT INTERNE DES OBJETS Jusqu’à présent nous avons laissé libre l’accès à l’état des objets depuis l’extérieur. Cela revient à exposer l’état interne des objets (valeurs des variables d’instance) vers l’extérieur. Si cette pratique peut paraître utile, elle est en réalité très dangereux et va à l’encontre du paradigme Orienté-Objet. ➽ Pourquoi cela est-il dangereux ? Quand une classe utilise un objet externe, le fait d’accéder directement à l’état interne de cet objet lui confère la possibilité de le modifier à sa guise. Par exemples : un joueur qui possède une donne pourrait modifier les dominos qu’elle contient !?! un joueur qui connaît la pioche peut en profiter pour piocher les dominos qui l’intéressent !?! ➽ Cela serait-il un problème ? On pourrait dire « non » puisque, si le code était fait de sorte qu’un joueur puisse piocher les dominos qui l’intéressent, cela se produirait pour TOUS les joueurs. Tout au plus, le programme tricherait mais, trichant pour tous les joueurs, il y aurait peu d’intérêt à écrire une tel programme. Cours JAVA (I21) -Licence 1 Semestre 2 / Y.Laborde
PROTECTION DE L’ÉTAT INTERNE DES OBJETS Cours Java (I21) - Licence 1 Semestre 2 / Y.Laborde 26/03/2017 PROTECTION DE L’ÉTAT INTERNE DES OBJETS ➽ Quel est le vrai problème ? En fait, il s’agit plus d’un problème de mauvaise conception des programmes. Dans le paradigme OO, ce que l’on désire avant tout c’est de structurer les programmes de sorte qu’ils soient facile à écrire, à comprendre, à corriger, à maintenir et à faire évoluer. Or, si l’on effectue de l’extérieur une partie des comportements normalement attendus dans une classe, il va vite devenir difficile de repérer tous les endroits où des modifications peuvent survenir sur un objet. L’écriture, la lecture, la correction, la maintenance et l’évolution en seront d’autant plus ardues. ➽ Quel est donc le point de vu de l’OO ? Le paradigme OO nous incite à respecter un point fondamental : « Ne pas faire faire à un objet ce qu’un autre saurait mieux faire. » Le joueur n’a pas à piocher directement dans la pioche, il doit utiliser une méthode d’instance de la pioche La pioche ne doit pas déléguer le fait de piocher On peut aussi dire : « Ne pas déléguer à d’autres ce que l’on sait faire mais ne pas faire ce que d’autres feraient mieux. » Seule la pioche doit permettre de piocher un domino pour assurer que cela est bien fait aléatoirement ! Seule la ligne de jeu peut accepter un domino à l’une de ses extrémités pour assurer que le domino est jouable ! Cours JAVA (I21) -Licence 1 Semestre 2 / Y.Laborde
PROTECTION DE L’ÉTAT INTERNE DES OBJETS (SUITE) Cours Java (I21) - Licence 1 Semestre 2 / Y.Laborde 26/03/2017 PROTECTION DE L’ÉTAT INTERNE DES OBJETS (SUITE) Ainsi le paradigme Orienté-Objet nous incite à voir les choses autrement : ➽ L’état interne d’un objet doit rester de la responsabilité de l’objet lui-même Par exemples : seule la pioche peut fournir un domino avec l’assurance qu’il ait été pioché au hasard ! seule une ligne de jeu peut accepter un domino à l’une de ses extrémités avec l’assurance qu’il puisse y être joué ! ➽ Pourquoi ? 1) c’est là un principe qui permet de garantir la cohérence constante de l’état interne des objets (on est assuré que la ligne de jeu ne comportera jamais de dominos mal placés) 2) c’est aussi ce qui rend les programmes OO faciles à maintenir, à corriger ou à faire évoluer (on sait facilement repérer les erreurs dans les programmes puisqu’une incohérence dans l’état d’un objet ne pourrait provenir que de l’objet lui-même – i.e. de ces méthodes d’instance) Une autre interprétation serait de dire : concevoir les objets en leur donnant le plus d’autonomie possible (le fait qu’une partie du comportement attendu pour un objet doive être traité extérieurement est le signe d’un manque d’autonomie de l’objet ; la classe de cet objet n’a pas été correctement conçue) n’utiliser les objets qu’au travers de leurs méthodes d’instance (en respectant l’usage des méthodes d’instance des objets, on évite d’éparpiller les traitements et on respecte l’autonomie des objets) ➽ Comment ? 1) les objets doivent protéger leurs états internes de l’extérieur en n’autorisant pas leur accès Cela est réalisé en déclarant les variables d’instance comme privées (ex: private int m1, m2;) 2) en contrepartie, les classes doivent fournir TOUTES les méthodes d’instance permettant de manipuler leurs objets depuis l’extérieur Cours JAVA (I21) -Licence 1 Semestre 2 / Y.Laborde
PROTECTION DE L’ÉTAT INTERNE DES OBJETS (SUITE) Cours Java (I21) - Licence 1 Semestre 2 / Y.Laborde 26/03/2017 PROTECTION DE L’ÉTAT INTERNE DES OBJETS (SUITE) Classes des cours et TD revisitées : classe Domino // Variables d’instance privées -m1: int -m2: int - = private + = public $ = static classe Pioche // Variable d’instance privée -laPioche: Domino[] ➽ Déclarations Java : // Variables d’instance privées private int m1, m2; private Domino[] laPioche; private Domino[] ldj; private Domino[] laDonne; classe LigneDeJeu // Variable d’instance privée -ldj: Domino[] classe DonneJoueur // Variable d’instance privée -laDonne: Domino[] Cours JAVA (I21) -Licence 1 Semestre 2 / Y.Laborde
(A) CLASSE ENCAPSULANT UN TABLEAU D’OBJETS Cours Java (I21) - Licence 1 Semestre 2 / Y.Laborde 26/03/2017 (A) CLASSE ENCAPSULANT UN TABLEAU D’OBJETS Résumé Nous avons vu : ➽ comment concevoir des classes qui encapsulent des tableaux d’objets (i.e. définir quelles méthodes d’instance nous seront utiles voire indispensables pour être en mesure de manipuler leurs objets le plus simplement possible depuis extérieur) ➽ comment écrire ces classes (i.e. faire des choix d’implémentation ; par exemple, construction à vide en utilisant null) ➽ comment faire interagir les objets par une utilisation correcte de la délégation (i.e. doter les bons objets des bonnes méthodes en prenant soin de relayer les traitements à réaliser jusqu’aux objets qui savent le mieux les faire) ➽ comment assurer la protection de l’état interne des objets depuis l’extérieur (i.e. interdire la visibilité directe des variables d’instance des objets en les déclarant private) Cours JAVA (I21) -Licence 1 Semestre 2 / Y.Laborde
Cours Java (I21) - Licence 1 Semestre 2 / Y.Laborde 26/03/2017 Acta est fabula Acta est fabula : « La pièce est jouée. » On annonçait ainsi la fin de la représentation dans le théâtre antique. C’est tout pour aujourd’hui : version plus moderne ! Cours JAVA (I21) -Licence 1 Semestre 2 / Y.Laborde