Diapositives
Transcription
Diapositives
1I2AC1 : Génie logiciel et Conception par objet Chapitre 2 Approche objet « Il existe deux manières de concevoir un logiciel. La première, c’est de le faire si simple qu’il est évident qu’il ne présente aucun problème. La seconde, c’est de le faire si compliqué qu’il ne présente aucun problème évident. La première méthode est de loin la plus complexe. » Antony R. Hoare, prix Turing 1980 Régis Clouard [email protected] ENSICAEN 14050 Caen 2 Objectifs de ce chapitre 1 Le paradigme 3 objet Les classes 2 Les objets 4 5 Associations Héritage entre et classes polymorphisme 3 Paradigme impératif On s'intéresse aux traitements : actigramme Programme : une séquence d'appels de fonctions Les données sont inertes : elles sont modifiées par les fonctions gérer_ascenseur clignoter_voyant initialiser_timer descendre_ascenseur ouvrir_porte fermer_porte descendre 4 Paradigme objet On s'intéresse aux données : datagramme Programme : un ensemble d'objets en interaction Les données sont animées : ce sont elles qui exécutent les fonctions :Porte ouvrir :Voyant :Cabine aller au RDC faire clignoter :Bouton 2-1 Conception impérative Méthode de conception : Algorithmique Trouver la séquence d'appels de fonctions Avantages Modélisation proche du fonctionnement de la machine Calculs de la complexité Preuves de programmes dans certains cas Limites Modélisation inaccessible aux clients / utilisateurs Inadaptée aux gros logiciels Nécessite de savoir résoudre le problème globalement L'enchaînement est figé dans le temps Maintenance difficile Interdépendance des fonctions entre elles et avec les données 5 Conception par objet Méthode de conception : Modélisation Trouver les objets du domaine d'application « Si je disposais d'un chapeau magique, quels types de données voudrais-je voir sortir du chapeau pour m'aider à résoudre le problème ? » Avantages Adaptée à une analyse « diviser – réunir » Maintenance facilitée : objets = blocs indépendants Permet d'appréhender la complexité (gros logiciels) Limites Approche moins intuitive 2-2 Vision locale du fonctionnement du logiciel Calculs de complexité et preuves difficiles (polymorphisme) 6 Concepts de la POO Différence entre langage impératif et langage orienté objet Ne concerne que quelques mots clés et types de données Mais ce sont deux paradigmes totalement différents La Programmation Orientée Objet (POO) s'appuie sur 5 concepts pour exprimer de manière uniforme toutes les étapes depuis l'analyse, la conception, la programmation jusqu'aux tests d'une application informatique : Objet Classe Association Héritage Polymorphisme 7 8 Objectifs de ce chapitre 3 Les classes 2 Les objets 4 5 Associations Héritage entre et classes polymorphisme Caractéristiques fondamentales Prosaïquement Objet = Structure en C + Pointeurs sur des fonctions Conceptuellement Objet = État interne + Responsabilité État : ensemble de données Possédant chacune une valeur Évoluant au cours du temps Responsabilité : ensemble de fonctions Agissant sur l'état de l'objet Déclenchées par stimulation externe AT-013-SR: AT-013-SR:Car Car color = blue weight= 979 kg power = 100 hp move() stop() refuel() 9 10 Encapsulation Penser un objet comme un fournisseur de services et pas comme une structure qui stocke des valeurs de données Services Objet Les données sont cachées et protégées, elles ne servent qu'à assurer les services Méthodes Attributs Communication entre objets L'unité de communication est le message Appel d'un service d'un objet Relation de communication dynamique Interactions pour réaliser les fonctionnalités du logiciel Séquence de messages échangés entre les objets 11 12 Objectifs de ce chapitre 3 Les classes 4 5 Associations Héritage entre et classes polymorphisme 13 Classe Représente un concept du problème Concept : une entité ayant une représentation dans le monde de la modélisation et surtout nommée. Ce qui n'est pas nommé n'existe pas. Une classe est une génératrice d'objets qui définit : La liste des propriétés La liste des services La liste des relations avec les autres classes Notation UML Rectangle Texte Casse : première lettre en majuscule (Camel case) En pratique : un substantif au singulier Propriétés Attributs qui définissent l'état interne des objets Données que possède tout objet de la classe (valeur unique) Ne peuvent être que d'un type primitif (ou assimilé) float, double, boolean, int, char, enumerate, string, int[], etc. Notation UML Placées dans un premier compartiment supplémentaire Texte 14 Casse : en minuscule En pratique : un substantif On peut ajouter le type une valeur par défaut la multiplicité (pour les tableaux, ensembles, …) Services Méthodes qui définissent le comportement des objets Fonctions classiques avec paramètres et valeur de retour type_retour nom( paramètre_formel* ) { } La signature d'une méthode nom + paramètres L'appel se fait par l’intermédiaire d'un objet de la classe Notation UML Placées dans un deuxième compartiment Texte Casse : en minuscule terminée par () En pratique : un verbe On peut ajouter La signature + la valeur de retour 15 Constructeur Méthode qui initialise les objets lors leur création Pas d'appel explicite au constructeur Appelé automatiquement à la construction d'une instance Notation UML Il n'y pas de notation spécifique en UML parce que les constructeurs sont une préoccupation d'implémentation (cf. encapsulation) En fonction du langage Nom de la classe en Java __init() en Python 16 Instance d'une classe = Objet Instance de classe Manifestation concrète d'une abstraction qui propose des services qui possède un état capable de mémoriser les effets des services Notation UML Un rectangle avec un nom souligné Texte Casse : première lettre en minuscule En pratique : un substantif Etudiant Etudiant <<instanceof>> paul paul: :Etudiant Etudiant 17 18 Objet Caractère une instance ne peut changer de classe Accès statique de l'instance toto:Papillon à un attribut ou une méthode Notation pointée toto:Chenille instance.attribut instance.operation() p.ex. pierre.calculeCotisation() L'auto-référence : 'this' ou 'self' pierre pierre: :AssureSocial AssureSocial calculeCotisation(): calculeCotisation():float float 19 Classe et Objet en Java Déclaration de la classe class class Car Car {{ String String color color == "green"; "green"; boolean boolean moving; moving; int int tank tank == 0; 0; Car(){ Car(){ moving moving == false; false; }} boolean boolean isMoving(){ isMoving(){ return return moving; moving; }} void void stop(){ stop(){ moving moving == false; false; }} void void refuel(int refuel(int liters){ liters){ tank tank == liters; liters; }} int int getTankLevel(){ getTankLevel(){ return return tank; tank; }} }} Création Car c = new Car(); Appel d'un objet : de services : c.stop(); c.refuel(32); Destruction d'un objet : c = null; Car Car color: string color: string=="vert" "vert" moving: boolean moving: boolean==false false tank: integer=0 tank: integer=0 Car() Car() isMoving() isMoving(): :boolean boolean stop() stop() refuel(litres: refuel(litres:integer) integer) getTankLevel(): getTankLevel():integer integer <<instanceof>> cc: :Car Car color= color="green" "green" moving=true moving=true tank=32 tank=32 20 Objectifs de ce chapitre 4 5 Associations Héritage entre et classes polymorphisme Associations Pour envoyer un message, il est impératif qu'il y ait une association entre les deux objets. Il faut que l'objet appelant connaisse l'adresse mémoire de l'objet appelé. Association Relation dynamique entre objets. Définie par la classe. Instanciée par les objets. 4 types d'association standard agrégation composition dépendance 21 Association standard Relation Relation organisationnelle Notation de type « connaît » UML Cas particulier des associations réflexives 22 Association de type agrégation 23 Relation structurelle de subordination non symétrique de type « possède » Une classe joue le rôle d'agrégat d'autres classes agrégées Relation Exemple Composé / Composant Voiture / Roue Collection / Élément Forêt / Arbre Espace / Position Desert / Oasis Événement / Étape Jour / Matin, Présentation / Introduction Association de type agrégation Notation UML Un losange vide du côté de l'agrégat Notation Java : tableau, liste, vecteur ... class class Team Team {{ Player[] Player[] _players _players == void void add( add( Player Player p, p, _players[i]= _players[i]= p; p; }} }} class class Player Player {{ }} new new int int Player[15]; Player[15]; ii )) {{ 24 Association de type composition Agrégation par valeur de type « est constitué de » S'interprète comme si la classe composant était incluse dans la classe composite et cachée à l'intérieur Durée de vie Si le composite est détruit (ou copié), les composants le sont aussi Exclusivité 25 Une classe ne peut le composant que d'une seule classe composite Relation Exemple Corps / Portion Corps / Tête Matière / Substance Eau / Hydrogène Activité / Phase Achat / Paiement Association de type composition Notation 26 UML Un losange plein du côté du composite Notation Java : tableau, liste, vecteur ... class class Cheval Cheval {{ Membre[] Membre[] _membres _membres == new new Membre[4]; Membre[4]; Cheval Cheval (( )) {{ for for (int (int i=0; i=0; i<4; i<4; i++) i++) {{ _membres[i] _membres[i] == new new Membre(); Membre(); }} }} }} class class Membre Membre {{ }} 2-3 Navigabilité des associations Restreindre l'accessibilité à un sens Notation UML une flèche ouverte Par défaut Navigable dans les deux sens Notation UML un trait entre les deux classes participantes 27 Rôle des associations Spécifier la fonction de la classe associée Notation UML Placé sur le bout de flèche de l'association Casse : en minuscule En pratique : un substantif 28 Multiplicité des associations 29 Définir le nombre d'instances de l'association pour une instance de la classe Un nombre entier ou un intervalle de valeurs 1 0..1 M..N * 1..* N Notation Un et un seul (obligatoire) Zéro ou un (facultatif) De M à N De zéro à plusieurs (quelconque) De 1 à plusieurs (au moins 1) Exactement N (exactement) UML Notée avec le rôle Par défaut 1 (non notée) 2-4 Contraintes sur les associations Association ordonnée unordered (c'est la valeur par défaut). ordered : les associés sont stockés dans un ordre précis. books Library members Book {ordered by date} * {ordered by surname} * Member Association qualifiée : tableau associatif Les éléments sont accessibles par une clé contient Dossier Fichier nom fichier 1..* * 30 31 Résumé de la notation Sens Rôle Nom Personne affecte() employés Qualification Entreprise emploie 1..* {ordered} addEmploye(Personne) Ordre sur les liens Classe nom Multiplicité Type d'association Les associations en Java Association avec une multiplicité connue a priori Multiplicité 0 ou 1 : une référence class Personne { Entreprise employeur; } Multiplicité de N : un tableau de N références class Entreprise { Personne[10] employes; } Association ArrayList ou LinkedList (selon les opérations) Association ordonnée TreeSet Association normale avec une multiplicité de '*' HashMap qualifiée 32 Implication des décorations La caractérisation des associations déterminent des contraintes qui influencent tant la construction que la destruction des instances. Implication dans le code Constructeur Structure de données : tableau, vecteur, table de hashage Principe de conception Les choix doivent levés et explicitement représentés Laisser le moins de latitude aux programmeurs. 33 Dépendance Relation entre objets qui n'est pas de nature structurelle Lien dynamique p. ex. paramètre ou variable locale. Notation UML Une flèche pointillée Remarque À noter que si cela est réellement explicatif Notation Java class class Voiture Voiture {{ CarteGrise CarteGrise obtenirCG() obtenirCG() {{ cg cg == new new CarteGrise(); CarteGrise(); cg.immatriculation="1234CG14"; cg.immatriculation="1234CG14"; return return gc; gc; }} }} 34 35 Objectifs de ce chapitre 5 Héritage et polymorphisme 36 Généralisation et spécialisation Deux Généralisation points de vue menant au mécanisme d'héritage Factoriser les éléments communs d'un ensemble de classes Une super-classe est une abstraction de ses sous-classes Généraliser Spécialisation Étendre les services et les propriétés Une sous-classe est un cas particulier de sa super-classe (un cas particulier) Spécialiser 2-5 Héritage Relation 37 très forte et statique Permet de construire une nouvelle classe à partir de classes existantes La classe dérivée contient par héritage tous les attributs et toutes les méthodes de la classe parent. Notation UML Une flèche triangulaire anonyme Vocabulaire Super-classe (super-class) Sous-classe (subclass) ou classe dérivée (derived class) Notation Java Le mot clé 'extends' class class Forme Forme {{ int int couleur; couleur; }} class class Cercle Cercle extends extends Forme Forme {{ int int rayon rayon void void afficher() afficher() {{ ... ... }} }} class class Rectangle Rectangle extends extends Forme Forme {{ void void afficher() afficher() {{ ... ... }} }} static static void void main(String main(String args[]) args[]) {{ Cercle Cercle cercle cercle == new new Cercle(); Cercle(); cercle.couleur cercle.couleur == 1; 1; cercle.afficher(); cercle.afficher(); }} 38 Transtypage Downcasting Un objet d'une classe dérivée peut être vu comme un objet de la super-classe Forme c1 = new Carre(); (accès aux seuls services de Forme) Rectangle c2 = new Carre(); (accès aux services de Forme et Rectangle) Carre c3 = new Carre(); c1 : Carre (accès aux services de Forme, Rectangle et Carre) Upcasting Un objet indexé comme un objet de super-classe peut être promu en un objet de classe dérivée s'il est effectivement du type de la classe dérivée Forme r = new Rectangle(); Rectangle r1 = (Rectangle)r; Carre c = (Carre)r; // Erreur à l'exécution 39 La portée des noms Il 40 est possible de définir des méthodes de même nom dans des classes sans rapport entre elles Permet de garder une vision locale des classes sans problème de conflit de nom avec d'autres classes Exemple Le choix de la méthode est fait à la compilation À partir de la classe de l'objet appelant. Liaison statique (early binding) La surcharge Surcharge (overloading) Dans une même portée, donner un même nom à des méthodes de signatures différentes Permet de définir des fonctions adaptées aux paramètres Exemple Le choix de la méthode est fait à la compilation À partir de la signature (liste des paramètres effectifs) Liaison statique (early binding) 41 Le polymorphisme * 42 (*Polymorphisme : peut prendre plusieurs formes) Redéfinition (overriding) Dans une même hiérarchie, donner le même nom à des fonctions de même signature. Exemple Le choix de la méthode est fait à l'exécution À partir du type de l'objet appelant Liaison dynamique (late binding) 2-6 Visibilité des membres Restreindre l'accès aux membres de la classe Attributs Méthodes Associations Privée (private) Restreinte aux seules instances directes de la classe Protégée (public) Notation UML : + Accessible à toutes les instances du projet Paquet (protected) Notation UML : # Restreinte aux instances directes de la classe et des classes dérivées Publique Notation UML : - (package) Notation UML : ~ Accessible à toutes les instances des classes du paquet 43 La visibilité des membres 44 Ordre Privé < protégé ≤ paquet < publique (Remarque : en Java protected donne aussi l'accès paquet) Les classes dérivées ne peuvent pas diminuer la visibilité d'une méthode redéfinie. Contrainte due à la compilation qui n'a pas moyen de vérifier le respect d'une visibilité plus restrictive Pour des questions de sécurité et de maintenance de code, il est important de limiter le plus possible la visibilité des membres La visibilité par défaut doit être privée En particulier, tous les attributs doivent toujours être privés (encapsulation) 2-7 La portée des membres Portée 45 syntaxique Niveau instance : ressource distincte pour chaque instance Niveau classe : ressource partagée par toutes les instances Remarque Une méthode de classe ne peut utiliser que des attributs de classe Notation UML Nom de l'attribut ou de la méthode en souligné Notation Java : le mot clé 'static' class class Math Math {{ public public static static int int PI PI == 3.141592; 3.141592; public static int rand(){} public static int rand(){} public public static static float float exp(float exp(float e1, e1, float float e2){} e2){} }} Math.PI; Math.PI; Math.exp(5.0f, Math.exp(5.0f, 2.0f); 2.0f); Classe abstraite Une classe dont on ne peut pas créer d'instance Notation UML Nom en italique ou stéréotype <<abstract>> Notation Java : le mot clé 'abstract' public abstract class Forme() { } Mais on peut créer des références Forme f = new Cercle(); Conséquence Une classe abstraite doit forcément posséder des classes dérivées. 46 Méthode abstraite Méthode sans implantation (sans code) Notation UML Nom en italique ou stéréotype <<abstract>> Notation Java : le mot clé 'abstract' abstract public void afficher(); Rôle : obliger les classes dérivées à redéfinir la méthode Exemple en Java Forme c1 = new Cercle(); c1.afficher(); Conséquences Une classe avec une méthode abstraite doit être de type classe abstraite Une classe abstraite peut ne contenir que des méthodes concrètes 47 48 Classe paramétrée Nommée generics en Java (template en C++ ) Un type générique à instancier Notation public class Ensemble<T> { public Ensemble() {} public void add(T x) { .. } public T get(int i) { .. } } Classe T Java Ensemble add(x: T) : void get(int index): T paramétrée Instanciation au moment de la déclaration En Java Ensemble<Client> e = new Ensemble<Client>(); e.add(new Client()); Client c = e.get(0); Ensemble<Integer> s = new Ensemble<Integer>(); Client Notion de type 49 Type Définit une liste de services que doit posséder une classe pour être utilisée par une autre classe. Oblige la classe à implémenter ces services si elle veut pouvoir être utilisée par l'autre classe. Un objet ne peut appartenir qu'à une classe mais peut être de plusieurs types. Exemple Objets de la classe Carré et de type Imprimable (service print()) Ordonnable (service sort()) Affichable (service display()), etc 50 Interface La notion de type est implémentée en Java par une interface Une structure dont toutes les méthodes sont abstraites. Une structure qui ne possède pas d'attribut. Une classe peut implémenter plusieurs interfaces. Notation UML : trois alternatives Une classe normale (3 compartiments) stéréotypée <<interface>> (à privilégier) Un rectangle avec 2 compartiments Un rond nommé <<Interface>> Ordonnable +superieur(): boolean +egal(): boolean Ordonnable +superieur(): boolean +egal(): boolean Ordonnable 51 Interface Relation Une classe qui implémente les méthodes d'une interface Notation d'implémentation UML Flèche fermée avec trait en pointillé Classification <<interface>> Ordonnable Marathonian Classification Annuaire Marathonian Ordonnable Interface Notation Java : <<interface>> Classification public interface Ordonnable { Ordonable public boolean superieur(); public boolean egal(); } public class Marathonian implements Ordonnable { Marathonian public boolean superieur() {..} public boolean egal() {..} // méthodes spécifiques } public class Classification { ArrayList<Ordonnable> coureurs; … coureurs.get(1).superieur(coureurs.get(2)); } 52 Concepts de la POO Classe et objet Encapsulation Masquage des informations Relation Héritage et polymorphisme Association Standard Agrégation Composition Dépendance Classe et Type 53 Modélisation objet Règle 1 : Modéliser le problème en laissant le moins de latitude aux programmeurs Les choix doivent être levés Règle 2 : Modéliser le problème en exprimant le plus de choses statiquement Vérifiables par un compilateur Règle 3 : Préférer les interfaces aux classes abstraites Plus légères Règle 4 : Restreindre le plus possible la visibilité des membres 54