l`approche objet - Site de Bertrand LIAUDET

publicité
UML
4 - Approche et modélisation objet
Objets et Classes
Diagramme de structure
Analyse organique
Bertrand LIAUDET
Le cours contient 2 parties : une partie théorique (l’approche objet) et une partie pratique (la
modélisation objet). La partie pratique peut être abordée indépendamment de la partie
théorique.
SOMMAIRE
L’APPROCHE OBJET
4 Les 5 paradigmes de programmation de Stroustrup (C++) : vers la P.O.O !
4 1 : PROCEDURE : pdg. de base, celui de la programmation procédurale
2 : MODULE (Package) : pdg. de la programmation modulaire : masquer
l’information
CLASSE : pdg. de l’abstraction des données : définir des types
4 : HERITAGE : pdg. de la programmation objet, celui de l’héritage
5 : GENERICITE : pdg. de la prog. générique (type variable, pattern, framework)
Programmation objet vs. programmation procédurale
Principe de la distinction
Avantages de l’approche objet
L’Objet
4 4 4 5 5 6 6 6 8 Présentation
Etat 8 Comportement
Identité
Syntaxe UML
Encapsulation
Persistance des objets
Transmission des objets
UML – Approche objet - introduction – page 1/51 - Bertrand LIAUDET
8 8 8 9 9 9 9 Scénario de communication
Communication entre objets
Collaboration et communication
3 catégories d’objet en fonction de leur mode communication
Le Message
9 10 10 10 12 Principes
Synchronisation des messages
Message synchrone
Message asynchrone
Message dérobant
Message minuté
La Classe
12 12 12 14 14 14 16 Classe, objet, instance
Les attributs d’une classe
Les principales catégories de méthodes
L’Héritage
16 16 16 18 Héritage et représentation ensembliste
18 Vocabulaire ensembliste
18 Abstrait / Concret – Abstraction - Abstraire
19 L’héritage en programmation objet
19 Principe de substitution
20 Attention à l’héritage des associations !
20 L’abstraction dans la programmation objet : un nouveau paradigme de
programmation
20 Le Polymorphisme
Principes
Remarques méthodologiques
21 21 21 MODELISATION OBJET PREMIERE APPROCHE
22 1. L’objet et sa classe
22 Exemple du téléviseur
Idée de la programmation objet
Petite méthode de conception objet
22 23 23 2. Définition d’une classe
24 Les attributs
Les opérations
Formalisme UML
24 24 25 4. La classe comme interface
2 types d’interface : proposée et utilisée
Formalisme UML
UML – Approche objet - introduction – page 2/51 - Bertrand LIAUDET
27 27 27 Conception par les interfaces
5. Composant logiciel
Présentation
Deux types de modularité
Abstraction
Encapsulation
Exemple
6. L’objet
29 31 31 31 31 31 32 34 Définition
Principes techniques
Lieux de déclaration – construction des objets
Provenance des objets d’une méthode
Syntaxe UML
7. La communication entre les objets : envoi de message
Principe général de l’envoi de message
Envoi de message et héritage
Syntaxe UML du diagramme de séquence
8. Exemple complet : la bibliothèque
Cahier des charges
Analyse des interfaces
Analyse des écrans
Analyse des scénarios
Diagramme des classes
9. Diagramme de classes et base de données : les classes « métier ».
Classes-métier et classes organiques
Classes-métier et base de données
Relations entre le modèle BD et le modèle objet
34 34 34 34 35 35 35 35 35 37 37 37 39 40 42 43 43 43 43 10. L’affichage et les écrans
46 11. La gestion des collections
47 12. Les 3 relations fondamentales entre les objets (et les classes) : composition,
utilisation, héritage
49 La composition
L’utilisation (ou dépenndance)
L’héritage
49 49 50 Première édition : automne 2007. Deuxième édition : novembre 2008. Troisième édition : octobre 2009 (chapitre
première approche) – Mise à jour octobre 2010
Edition juillet 2015
UML – Approche objet - introduction – page 3/51 - Bertrand LIAUDET
L’APPROCHE OBJET
Le cours contient 2 parties : une partie théorique (l’approche objet) et une partie pratique (la
modélisation objet). La partie pratique peut être abordée indépendamment de la partie
théorique.
Les 5 paradigmes de programmation de Stroustrup (C++) : vers la P.O.O !
Pour le compilateur, la différence entre le C et le C++ se limite à quelques mots clés
supplémentaires et quelques types de données supplémentaires.
Pour le programmeur, le passage d’une approche procédurale (on dit aussi fonctionnelle) à une
approche « objet », c’est une nouvelle façon de programmer, un nouveau paradigme.
Stroustrup, créateur du C++, distingue 5 paradigmes de programmation :
PROCEDURE
MODULE
CLASSE
HERITAGE
GENERICITE
1 : PROCEDURE : pdg. de base, celui de la programmation procédurale
Choisissez les procédures.
Utiliser les meilleurs algorithmes que vous pourrez trouver.
Utilisation de fonctions : définissez les entrées et les sorties.
2 : MODULE (Package) : pdg. de la programmation modulaire : masquer l’information
Choisissez vos modules (fichiers avec des fonctions).
Découpez le programme de telle sorte
que les données soient masquées par les modules
Le paradigme de la programmation modulaire est en partie rendue obsolète par l’usage de la
programmation objet.
Utilisation de static, extern, espace des noms : outils.c, outils.h (interface), utilisation.c.
CLASSE : pdg. de l’abstraction des données : définir des types
UML – Approche objet - introduction – page 4/51 - Bertrand LIAUDET
Choisissez les types dont vous avez besoin.
Fournissez un ensemble complet d’opérations pour chaque type.
Il y a 3 sortes de types :
•
Les types définis par module (utilisation de référence, autre nom pour un objet)
•
Les types concrets définis par l’utilisateur : les classes (niveau interne, « organique ») « ces
types ne sont pas « abstraits » : ils sont aussi réels que int et float.
•
Les types abstraits définis par l’utilisateur : les interfaces (niveau externe, « fonctionnel »)
Fabriquer un type structuré consiste à regrouper des types (simples ou déjà structurés) dans un
même type structuré : c’est déjà un mécanisme d’abstraction.
La définition des types structurés et des opérations qui leurs sont associées correspond à la
notion de TAD (type abstrait de donnée) et conduit directement à la notion de classe (rappelons
qu’une classe c’est un type, en général structuré, auquel on ajoute des procédures).
4 : HERITAGE : pdg. de la programmation objet, celui de l’héritage
Choisissez vos classes.
Fournissez un ensemble complet d’opérations pour chaque classe.
Rendez toute similitude explicite à l’aide de l’héritage.
5 : GENERICITE : pdg. de la prog. générique (type variable, pattern, framework)
Choisissez vos algorithmes.
Paramétrez-les de façon qu’ils soient en mesure de fonctionner
avec une variétés de types et de structures de données appropriées.
UML – Approche objet - introduction – page 5/51 - Bertrand LIAUDET
Programmation objet vs. programmation procédurale
Principe de la distinction
Approche procédurale ou fonctionnelle : ce que le système fait
•
L’approche procédurale propose une méthode de décomposition basée uniquement sur ce
que le système fait, c’est-à-dire aux fonctions du système On s’intéresse d’abord aux
fonctions puis aux données manipulées par les fonctions. Les fonctions sont identifiées
puis décomposées en sous-fonctions, et ainsi de suite jusqu’à l’obtention d’éléments
simples programmables.
•
C’est la méthode cartésienne ou analytique.
•
L’architecture du système montre finalement un système unique avec une architecture
hiérarchique des fonctions.
Approche objet : démarche systémique : ce que le système est et fait
•
L’approche objet propose une méthode de décomposition non pas basée uniquement sur ce
que le système fait, mais sur ce que le système est et fait. Autrement dit, on s’intéresse à
des ensembles de fonctions associées chacun à un ensemble de données, le tout
formant un objet. L’objet est une unité de services rendus (ses fonctions). Les fonctions et
sont identifiées par objet et pour un objet et non plus à partir de l’ensemble du système.
Les données sont identifiées par objet et pour un objet et non plus à partir des fonctions ou
de l’ensemble du système.
•
C’est la méthode systémique : les objets collaborent entre eux pour constituer le système.
On peut en rajouter ou en supprimer sans perturber les collaborations entre les objets non
concernés.
•
L’architecture du système montre finalement un ensemble de sous-systèmes considérés
comme des objets. C’est la description de ce que le système est. Chaque sous-système ou
objet intègre sont jeu de fonctions. C’est la description de ce que le système fait à travers
ce que font chacun des sous-systèmes ou objets.
Avantages de l’approche objet
•
Stabilité de la modélisation par rapport aux entités du monde réel.
•
Construction itérative facilitée par le couplage faible entre les composants (les soussystèmes ou objets).
•
Possibilité d’une réutilisation les composants d’un développement à un autre.
•
Simplicité du modèle. La programmation objet est basée sur 5 concepts fondateurs :
1. Objet
UML – Approche objet - introduction – page 6/51 - Bertrand LIAUDET
2. Message (l’échange entre deux objets)
3. Classe (la généralisation de l’objet)
4. Héritage (la factorisation de propriétés et de fonctions entre 2 classes)
5. Polymorphisme
UML – Approche objet - introduction – page 7/51 - Bertrand LIAUDET
L’Objet
Présentation
Objet = une identité + un état + un comportement
On dit aussi :
Objet = données (état) + méthodes (comportement, rôles, responsabilités)
D’un point de vue abstrait, un objet informatique est une représentation d’un objet (une
réalité) du monde extérieur. Cette représentation est caractérisée par des valeurs et des rôles à
jouer.
D’un point de vue informatique, un objet informatique est une variable avec un ou plusieurs
champs qui seront manipulés (en lecture ou en écriture) par les fonctions associées à l’objet (les
méthodes). Cette variable est aussi associée à des fonctions de plus haut niveau : les
responsabilités ou rôles.
Etat
Valeurs instantanées des attributs (des données) d’un objet.
Certaines parties de l’état peuvent évoluer au cours du temps.
D’autres parties de l’état peuvent être constantes.
Comportement
Le comportement regroupe les méthodes (ou compétences ou responsabilités ou rôles) d’un
objet.
Les méthodes sont des fonctions qui permettent d’accéder aux valeurs des attributs d’un objet
mais aussi des fonctions de plus haut niveau (responsabilités et rôles).
Ces méthodes sont déclenchées par des stimulations externes : des messages envoyés par
d’autres objets (c’est-à-dire des appels de méthodes).
Identité
Chaque objet possède une identité attribuée de manière implicite à la création de l’objet et
jamais modifiée (c’est son adresse en mémoire).
On peut donner un attribut clé à l’objet, qu’on appelle « clé naturelle » (par exemple, un
numéro de sécurité sociale). Il s’agit toutefois d’un artifice de réalisation. Cette clé appartient à
l’état de l’objet. Le concept d’identité est indépendant du concept d’état.
Les objets sont différenciés par leurs noms (comme un nom de variable).
UML – Approche objet - introduction – page 8/51 - Bertrand LIAUDET
Toutefois, il est parfois difficile de nommer tous les objets : on peut donc les nommer du nom
de leur classe, avec « : » devant.
Syntaxe UML
Les objets sont soulignés et placés dans un rectangle. Le nom de l’objet commence par une
minuscule. Le nom de la classe commence par un majuscule.
Objets nommés :
olivier
bertrand
Objets sans noms :
: Eleve
: Professeur
Encapsulation
Pour accéder, en consultation ou en modification, à l’état d’un objet (à ses données), il faut
passer par ses fonctions (ses méthodes). Il faut que ces fonctions soient appelées par d’autres
fonctions qui peuvent être des méthodes du même objet ou d’un autre.
Quand une méthode d’un objet 2 est appelée par une méthode d’un objet 1, on dit que l’objet
1 a envoyé un message à l’objet 2. Le message, c’est la méthode de l’objet 2.
Donc, de façon générale, pour accéder à l’état d’un objet, il faut lui envoyer un message.
Les méthodes sont l’interface obligatoire d’accès aux données d’un objet.
Persistance des objets
Un objet persistant sauvegarde son état dans un système de stockage permanent, de sorte qu’il
est possible d’arrêter le processus qui l’a créé sans perdre l’information représentée par l’objet.
C’est la passivation de l’objet.
L’activation de l’objet consiste à reconstruire l’objet dans l’état dans lequel on l’avait
sauvegarder.
Par défaut, les objets ne sont pas persistants.
Transmission des objets
La transmission des objets consiste à faire passer un objet, par un moyen de communication
quelconque, d’un système à un autre.
Scénario de communication
L’objet révèle son vrai rôle et sa vraie responsabilité lorsque, par l’intermédiaire de l’envoi de
messages, il s’insère dans un scénario de communication (c’est-à-dire un cas d’utilisation
concret du système).
UML – Approche objet - introduction – page 9/51 - Bertrand LIAUDET
Atterir
: Tour de contrôle
: Avion
[en vol]
L’objet « Avion » a dans ses méthodes la fonction « Atterrir ».
L’objet « Tour de contrôle » a dans ses données un objet avion ou un pointeur sur un objet
avion. Une méthode de l’objet « Tour de contrôle » peut donc envoyer un message à l’objet
« Avion », c’est-à-dire faire appel à la fonction « Atterrir ». Autrement dit, envoyer un
message, c’est appeler une fonction : un message, c’est un ordre impératif !
Communication entre objets
Un système informatique peut être vu comme une société d’objets qui communiquent entre eux
pour réaliser les fonctionnalités de l’application.
Le comportement global d’une application repose sur la communication
entre les objets qui la composent.
De ce fait, l’étude des relations entre les objets du domaine est de première importance dans la
modélisation objet.
De plus, la première communication étant la communication entre les utilisateurs (acteurs
externes) et le système, on peut aussi partir de l’analyse fonctionnelle pour trouver les classes.
Collaboration et communication
On peut parler indifféremment de communication ou de collaboration entre objet.
Cependant, on parle plutôt de collaboration quand on décrit les communications nécessaires
pour réaliser une fonctionnalité. La collaboration est plutôt finalisée.
On parle par contre indifféremment de communication pour une communication atomique ou
une collaboration.
3 catégories d’objet en fonction de leur mode de communication
Un objet peut être :
- émetteur de message sans jamais en recevoir,
- destinataire de message sans jamais en émettre,
- émetteur et destinataire de message.
Les acteurs : client, thread
UML – Approche objet - introduction – page 10/51 - Bertrand LIAUDET
Ce sont des objets à l’origine d’une interaction. Ce sont des objets actifs. Il possède un « fil
d’exécution » : un thread. Ils passent la main aux autres objets. On peut les appeler
« client ».
Les serveurs
Ce sont des objets qui ne sont jamais à l’origine d’une interaction. Ils sont toujours
destinataire des messages et ensuite ils répondent. Ce sont des objets passifs.
Les agents
Ce sont des objets qui cumulent les caractéristiques des acteurs et des serveurs. Ils peuvent
interagir avec les autres objets à tout moment, de leur propre initiative ou suite à une
sollicitation externe.
Les agents permettent le mécanisme de délégation. Un client peut communiquer avec un
serveur qu’il ne connaît pas via un agent. Les agents découplent les acteurs des serveurs en
introduisant une indirection dans le mécanisme de propagation des messages.
UML – Approche objet - introduction – page 11/51 - Bertrand LIAUDET
Le Message
Principes
•
L’unité de communication entre les objets est le message.
•
L’envoi de message s’apparente à un appel de fonction.
•
Cependant, il n’y a pas de correspondance statique prédéfinie entre le nom de l’appel et le
code effectivement exécuté. En effet, l’appel de fonction de la programmation procédurale
correspond à un branchement sur la fonction à partir d’une table d’adresses. Le mécanisme
d’envoi de message consiste à remonter à la classe pour trouver la fonction et à remonter la
hiérarchie des classes jusqu’à trouver la fonction correspondante tant au niveau du nom
qu’au niveau des paramètres (polymorphisme). Si aucune fonction n’est trouvée, alors il y
aura un message d’erreur.
•
Le message acquiert toute sa force d’intégration lorsqu’il est associé au polymorphisme et
à la liaison dynamique.
Synchronisation des messages
La synchronisation précise la nature de la communication et les règles qui régissent le passage
des messages.
Message synchrone
Une fois le message envoyé, l’expéditeur est bloqué jusqu’à ce que le destinataire accepte le
message.
Un appel de procédure est un message synchrone.
Diagramme de collaboration correspondant :
Envoi simple
Un expéditeur
Un destinataire
Diagramme de séquence correspondant :
Un expéditeur
Un destinataire
Envoi simple
retour implicite
UML – Approche objet - introduction – page 12/51 - Bertrand LIAUDET
UML – Approche objet - introduction – page 13/51 - Bertrand LIAUDET
Message asynchrone
Il n’interrompt pas l’exécution de l’expéditeur.
L’expéditeur envoie le message sans savoir quand ni même si le message sera traité par le
destinataire.
Diagramme de collaboration correspondant :
Envoi simple
Un expéditeur
Un destinataire
Diagramme de séquence correspondant :
Un expéditeur
Un destinataire
Envoi simple
retour implicite
Ø
Demi flèche ou flèche simple peuvent représenter les envois asynchrones.
Message dérobant
Un message dérobant déclenche une opération seulement si le destinataire s’est préalablement
mis en attente du message.
Dans le cas d’un message synchrone, l’expéditeur accepte d’attendre ; dans le cas d’un
message dérobant, le destinataire accepte d’attendre.
Envoi dérobant
Message minuté
Un message minuté bloque l’expéditeur pendant un temps donné, en attendant la prise en
compte de l’envoi par le destinataire, ou la durée spécifiée dans le message.
UML – Approche objet - introduction – page 14/51 - Bertrand LIAUDET
Envoi minuté
UML – Approche objet - introduction – page 15/51 - Bertrand LIAUDET
La Classe
Classe, objet, instance
Une classe est la description d’un ensemble d’objets ayant les mêmes méthodes et les mêmes
types de données.
La classe peut être vue comme une extension de la notion de type.
L’objet est la réalisation concrète de la classe : un objet est une instance d’une classe.
Les objets apparaissent alors comme des variables de type classe.
Les attributs d’une classe
Ils sont définis par un nom, un type et éventuellement une valeur initiale. En général leur valeur
est variable pour chaque instance de la classe (chaque objet). Toutefois, il existe des attributs
constants au niveau de la classe : leur valeur sera la même pour chaque instance de la classe.
Chat
Nom :string
Age : int
Classe Chat
: Chat
Nom= ”Minou”
Age= 1
Un objet Chat
Les principales catégories de méthodes
•
Les constructeurs : pour créer les objets (création).
•
Les destructeurs : pour détruire les objets (destruction).
•
Les sélecteurs : pour renvoyer tout ou partie de l’état d’un objet (consultation).
•
Les modificateurs : pour modifier tout ou partie de l’état d’un objet (modification).
•
Les itérateurs : pour consulter le contenu d’une structure de données qui contient
plusieurs objets.
UML – Approche objet - introduction – page 16/51 - Bertrand LIAUDET
•
Les responsabilités ou rôles : ces méthodes correspondent aux fonction de haut niveau
permettant la réalisation des fonctionnalités du système. En phase de conception, on
s’intéresse surtout à ces méthodes.
UML – Approche objet - introduction – page 17/51 - Bertrand LIAUDET
L’Héritage
Héritage et représentation ensembliste
La représentation ensembliste permet de concevoir aisément la notion héritage : il suffit de
concevoir l’inclusion d’un ensemble dans un autre.
L’ensemble inférieur hérite des propriétés et des associations de l’ensemble supérieur : l’espèce
hérite des attributs du genre.
Un ensemble fait hériter ses attributs à tous les ensembles de niveaux inférieurs qu’il contient.
Le genre fait hériter à toutes ses espèces.
Cette organisation forme une hiérarchie, c’est la hiérarchie de spécialisation/généralisation,
encore appelée hiérarchie « is-a », « est-un ».
Formalisme ensembliste
Chats
Siamois
Minou
Minette
Chaque élément d’un ensemble est aussi élément des ensembles qui le contiennent : « Minou »,
c’est mon chat siamois : il appartient à l’ensemble des Siamois, mais aussi à l’ensemble des
Chats. Minette c’est le chat siamois de la voisine.
Vocabulaire ensembliste
Classe : ensemble, entité, table
On peut considérer les classes comme des ensembles. Les attributs de la classe sont les attributs
de l’ensemble. Chaque objet est un élément de l’ensemble.
La notion rejoint celle d’entité et de table.
Objet : élément, tuple
L’objet correspond à un élément d’un ensemble.
La notion rejoint celle de tuple (ligne de la table).
UML – Approche objet - introduction – page 18/51 - Bertrand LIAUDET
Sous-ensemble : espèce, classe-enfant, classe-mère
L’espèce est un sous-ensemble de l’ensemble dont on parle : le siamois est une espèce de chat.
Quand on parle d’un sous-ensemble, on dit aussi : « classe-enfant ». Quand on parle de
l’ensemble incluant, on dit aussi : « classe-mère ».
Sur-ensemble : genre, classe-mère
Le genre est un « sur-ensemble » de l’ensemble dont on parle : le chat est le genre du siamois.
Quand on parle d’un « sur-ensemble », on dit aussi : « classe-parent » ou « classe-mère ».
Abstrait / Concret – Abstraction - Abstraire
L’abstraction, c’est la classe !
Tous les noms d’ensemble sont abstraits : ce sont des abstractions. Une classe est donc toujours
abstraite d’un certain point de vue : ce qui est concret, c’est l’objet instance de la classe.
Les seules choses concrètes, ce sont les éléments de l’ensemble, c’est-à-dire les objets (Minou,
mon chat siamois).
Toutefois, UML définit particulièrement la classe abstraite, par opposition aux autres : une
classe abstraite est une classe pour laquelle il n’y a pas d’instanciations d’objet. Elle sert
uniquement à porter des spécifications en tant que classe-mère pour une classe « concrète ».
Abstraire
Abstraire, c’est remonter du concret à l’abstrait, donc des objets à la classe qui les englobe.
Par exemple de Minou et Minette au Siamois, ou de Minou et Minette au Chat.
Abstraire, c’est aussi remonter de l'espèce au genre, c’est-à-dire d’une classe-enfant à une
classe-parent. Par exemple du Siamois et de l’Angora au Chat.
Abstraire consiste à trouver des attributs communs à plusieurs ensembles ou à plusieurs choses
concrètes pour définir un ensemble qui portera ces attributs et qui inclura les ensembles ou les
choses concrètes en question.
L’héritage en programmation objet
L’héritage est une technique qui permet de construire une classe (espèce) en lui faisant hériter
des attributs et des méthodes d’autres classes (genre, classe-parent, classe-mère, super-classe).
L’héritage est utilisé pour :
•
construire de nouvelles classes qui héritent de caractéristiques existants déjà (héritage
d’une classe fenêtre)
•
classer les objets (taxonomie)
•
le polymorphisme (possibilité qu’une même méthode se réalise différemment)
•
la conception abstraite (conception de « haut niveau », éloignée du codage concrêt).
UML – Approche objet - introduction – page 19/51 - Bertrand LIAUDET
Animal
+ crier ()
+ manger ()
Chat
Chien
+ crier ()
+ crier ()
héritage avec polymorphisme
Principe de substitution
On peut substituer n’importe quel objet d’une super-classe par n’importe quel objet d’une
sous-classe. La spécialisation ajoute des attributs et des opérations mais ni n’en détruit, ni
n’en modifie.
Attention à l’héritage des associations !
Les associations sont héritées mais pas complètement ! ! !
Le plus souvent, les contraintes des associations ne sont pas transmises automatiquement de la
super-classe vers la sous-classe. Les contraintes sont le plus souvent traduites par un bout de
code implanté dans la réalisation d’une opération. Comme les langages permettent la
redéfinition des opérations dans les sous-classes, les programmeurs peuvent involontairement
introduire des incohérences entre la spécification d’une super-classe et sa réalisation dans une
des sous-classes.
L’abstraction dans la programmation objet : un nouveau paradigme de programmation
L’abstraction consiste à regrouper les éléments qui se ressemblent et à distinguer des structures
de plus haut niveau d’abstraction, débarrassées de détails inutiles.
La classe décrit le domaine de définition d’un ensemble d’objets.
Les généralités sont contenues dans la classe.
Les particularités sont contenues dans les objets.
Avec les langages-objet, le programmeur peut construire une représentation informatique des
abstractions de haut niveau correspondant aux usages mêmes de l’application, sans traduction
vers des concepts de plus bas niveau, comme les variables, les types abstraits de données et les
fonctions des langages non objet.
UML – Approche objet - introduction – page 20/51 - Bertrand LIAUDET
Le Polymorphisme
Principes
•
Le polymorphisme décrit la caractéristique d’un élément qui peut prendre plusieurs
formes (l’eau peut être à l’état solide, liquide ou gazeux).
•
Le polymorphisme désigne le principe qui fait qu’un nom d’objet peut désigner des
objets de différentes classes issus d’une même arborescence.
•
Le polymorphisme désigne surtout le polymorphisme d’opération : la possibilité de
déclencher des opérations différentes en réponse à un même message.
•
Le polymorphisme est lié à la notion d’héritage. On peut manipuler des objets dont le type
est abstrait au niveau de la classe générale (abstraite). Le type deviendra concret quand
l’objet deviendra concret et portera le type de sa classe spécialisée.
•
Le polymorphisme permet de manipuler des objets sans en connaître précisément le type :
c’est un cas de généricité.
Remarques méthodologiques
•
Le polymorphisme concerne le codage du corps des différentes méthodes. Par rapport à la
conception, c’est une notion qui intervient à bas niveau.
•
Il ne faut pas penser l’analyse en terme de polymorphisme, mais en terme d’abstraction (et
donc d’héritage). L’analyse en terme d’abstraction rend possible le polymorphisme au
niveau concrêt.
•
Les bénéfices du polymorphisme sont un plus grand découplage entre les objets : ils sont
avant tout récoltés durant la maintenance.
UML – Approche objet - introduction – page 21/51 - Bertrand LIAUDET
MODELISATION OBJET
PREMIERE APPROCHE
1.
L’objet et sa classe
Dans le monde réel, on trouve des objets statiques (une table, une statue, etc.) et des objets
coopératifs (une téléviseur, un robot-mixeur, etc.).
Exemple du téléviseur
Caractéristiques communes : le téléviseur abstrait
Tous les téléviseurs n’ont pas les mêmes caractéristiques, mais tous les téléviseurs ont des
caractéristiques communes. Ces caractéristiques sont de trois sortes :
•
les caractéristiques de ce qu’il est
•
les caractéristiques de ce qu’il fait (= de ce qu’il sait faire, =de ce qu’on peut en faire, =des
services qu’il peut rendre, =des services qu’on peut lui demander)
•
les caractéristiques de ses relations avec le monde extérieur
Caractéristiques de ce qu’il est
Tous les téléviseurs ont une marque, un écran, des haut-parleurs, des circuits pour capter et
transmettre l’image et le son, etc.
Caractéristiques de ce qu’il fait (les services qu’il rend)
Tous les téléviseurs ont un mécanisme de mise sous tension et d’arrêt, de changement de
chaînes, de réglage des images et du son, etc.
Caractéristiques de ses relations (interfaces) avec le monde extérieur
Le téléviseur fonctionne si la prise de courant est branchée et si l’antenne ou le câble sont
connectées.
La télécommande permet d’adresser des signaux de changement d’état à la télévision pour
utiliser ses services : allumer, éteindre, monter le son, baisser le son, choisir une chaîne, etc.
Remarques :
•
Un téléviseur peut être déplacé d’une pièce à l’autre et continuer à fonctionner tant que ses
relations avec le monde extérieurs sont maintenues.
UML – Approche objet - introduction – page 22/51 - Bertrand LIAUDET
•
L’utilisateur d’un téléviseur doit uniquement savoir brancher la prise de courant, brancher
l’antenne ou le câble, utiliser la télécommande. Il ne sait pas comment fonctionne un
téléviseur.
Abstrait et concret : classe et objet
Cette description présente le concept de téléviseur. C’est une présentation abstraite (générale,
théorique) : il n’est pas question d’un téléviseur réel, concret. Cette description correspond à la
notion de classe (analogue à la notion de type en programmation procédurale).
Tous les téléviseurs concrets sont construit à partir du même plan de base. Ce sont les objets
(analogue à la notion de variable en programmation procédurale).
Gestion des pannes
En cas de panne du téléviseur, on cherche le problème soit au niveau de ses dépendances avec
le monde extérieur, soit au niveau des services rendus par le téléviseur.
Idée de la programmation objet
L’idée de la programmation objet est de mimer ou simuler les objets du monde réel, que ce
soit des objets statiques ou des objets coopératifs. Les objets statiques sont des objets qui seront
utilisés par d’autres objets.
Déterminer quels sont les objets du monde réel à considérer constitue la base de la
démarche objet. C’est une démarche radicalement différente de la démarche procédurale qui
consiste à séparer les données passives et les instructions de calcul sur ces données. Le
paradigme objet unifie les données et les opérations dans un même module : l’objet.
La compréhension d’un objet est obtenue à travers les informations qui le caractérise, mais
aussi à travers les opérations ou les services qu’on peut lui demander, qu’on appelle encore
ses responsabilités. Un objet est défini par un mode d’emploi, c’est-à-dire la liste des
opérations qu’on peut appliquer à tous les objets de même nature.
Cette compréhension est formalisée dans un modèle qui est la classe de l’objet.
Petite méthode de conception objet
A partir d’un cahier des charges :
•
Dans un premier temps on recense les noms communs et les verbes qu’on juge important.
•
Dans un second temps, on regroupe les opérations correspondant à des verbes avec les
objets désignés par un nom commun. C’est la que se trouve la principale difficulté. La
relation entre l’opération et l’objet doit valoir pour tous les objets de même nature
(mettreSousTension () vaut pour tous les téléviseurs). En général, d’un point de vue
grammatical, l’objet est complément d’objet (direct ou indirect) de l’opération (mettre
sous tension quoi : le téléviseur, changer la chaîne de quoi : du téléviseur, etc.).
UML – Approche objet - introduction – page 23/51 - Bertrand LIAUDET
2.
Définition d’une classe
Une classe est un modèle à partir duquel on pourra construire les objets. C’est un analogue de
la notion de type.
Les attributs
Les attributs d’une classe peuvent être vus comme les champs d’un type structuré. Dans la
classe, on peut donner des valeurs par défaut aux attributs. Une valeur par défaut peut être non
modifiable : ces des constantes. Quand on crée un objet, les valeurs par défaut sont
automatiquement affectées aux champs concernés.
De plus, la visibilité et l’accès aux champs peuvent être réglementée. En général, les attributs
sont privés : ils ne seront visibles que par les opérations de la classe.
La classe comme type abstrait
Le téléviseur a une alimentation, un ampli audio, un tube vidéo, etc. Ces caractéristiques sont
des attributs du téléviseur. Le type de ces attributs est la classe correspondant à un objet
alimentation, un objet ampli audio, etc.
Cette approche permet de concevoir de façon à la fois abstraite et concrète : l’abstraction de la
classe Alimentation sera finalement réalisée.
Les opérations
Une classe contient des opérations. Les opérations sont des procédures et des fonctions.
Distinction entre en-tête et implémentation d’une opérations
ü L’en-tête décrit les paramètres en entrée et en sortie de l’opération, c’est-à-dire la façon
dont on peut utiliser une opération. On parle de spécifications d’une opération.
ü Le corps de l’opération est son implémentation.
Dans un premier temps, on ne précise que l’en-tête des opérations.
Distinction entre paramètres publiques et paramètres privés
ü Les paramètres privés sont les attributs de la classe de l’opération. Ils n’apparaissent pas
dans l’en-tête.
ü Les paramètres publics ne sont pas attributs de la classe. Ils apparaissent dans l’en-tête.
Distinction entre opérations publiques et des opérations privées
ü Les opérations publiques représentent les fonctionnalités, ou responsabilités, ou services
offerts par la classe. Elles disent à quoi sert la classe. Elles permettent de comprendre ce
UML – Approche objet - introduction – page 24/51 - Bertrand LIAUDET
qu’est la classe. Elles permettent d’utiliser la classe. Les opérations publiques sont visibles
par tout le monde.
ü Les opérations privées ne sont pas utiles pour le monde extérieur. Ce sont des opérations
qui servent aux opérations publiques.
Dans un premier temps, on ne précise que les opération publiques.
Distinction entre fonctionnel et organique
Les 3 distinctions précédentes sont des distinctions entre le fonctionnel et l’organique (le quoi
et le comment, l’externe et l’interne, le visible et le caché, le public et le privé).
Dans un premier temps, on s’intéresse à l’en-tête des opérations publiques en se limitant aux
paramètres formels qui ne sont pas attribut de la classe de l’opération.
Formalisme UML
Classe avec des attributs de type Classe
TÈlÈviseur
+
+
+
+
+
marque
alimentation
ampli
niveauSon
etc...
:
:
:
:
:
String
Alimentation
Ampli
int
int
mettreEnMarche ()
arrÍ ter ()
monterSon ()
: int
baisserSon ()
: int
etc... ()
ü le nom des attributs et des opérations commence par une minuscule.
ü Les types simple commencent par une minuscule (int), les types abstraits commencent par
une majuscule (Alimentation, String, etc.)
ü Les attributs sont privés : « - » devant
ü Les opérations sont publiques : « + » devant.
Composition à la place des attributs de type classe
Le modèle suivant est équivalent au précédent.
UML – Approche objet - introduction – page 25/51 - Bertrand LIAUDET
TÈlÈviseur
- marque : string
- etc...
: int
+ etc... ()
1
ampli
Ampli
1
Alimentation
Alimentation
- niveauSon : int
+ monterSon () : int
+ baisserSon ()
+ mettreEnMarche ()
+ arrÍ ter ()
UML – Approche objet - introduction – page 26/51 - Bertrand LIAUDET
4.
La classe comme interface
2 types d’interface : proposée et utilisée
Interface proposée
La télécommande du téléviseur est l’interface par laquelle on peut utiliser le téléviseur. C’est
l’interface proposée par l’objet. On peut changer d’interface sans changer de téléviseur.
L’interface
La modélisation objet permet de définir une classe spéciale appelée «interface » et qui permet
de définir uniquement l’en-tête des opérations. Les interfaces sont des classes abstraites car
aucun objet ne les réalisera. Le corps des opérations n’est pas définit non plus. C’est la classe
qui réalise l’interface qui définira le corps des opérations.
Dans notre exemple, les usages du téléviseur : allumer, éteindre, monter le son, etc., font partie
de son interface. Ils sont réalisée par l’objet téléviseur.
La télécommande est un nouvel objet (qui donne lieu à une nouvelle classe) qui va utiliser
l’interface des « usages grand public » du téléviseur.
Interface utilisée
Les prises électriques et les prises câble ou antenne sont les interfaces proposés par les objets
« réseau électrique », « réseau de câble » ou « antenne ». Ce sont les interfaces utilisés par le
téléviseur pour qu’il puisse fonctionner.
Formalisme UML
Interface proposée
<<interface>>
UsagesGrandPublicDuTÈlÈviseur
TÈlÈviseur
+
+
+
+
+
marque
alimentation
ampli
niveauSon
etc...
:
:
:
:
:
String
Alimentation
Ampli
int
int
<<use>>
<<rÈalise>>
+
+
+
+
TÈlÈcommande
mettreEnMarche ()
arrÍ ter ()
monterSon ()
: int
baisserSon ()
: int
mettreEnMarche ()
arrÍ ter ()
monterSon ()
: int
baisserSon ()
: int
etc... ()
La classe « UsagesGrandPublicDuTéléviseur » est stéréotypée « interface ». Le Téléviseur
« réalise » l’interface UsagesGrandPublicDuTéléviseur .
UML – Approche objet - introduction – page 27/51 - Bertrand LIAUDET
Le lien de réalisation est en pointillé. La flèche est un triangle creux (comme pour l’héritage).
Le lien peut être stéréotypé « réalise ».
La classe « télécommande » utilise l’interface : la télécommande à besoin de l’interface pour
fonctionner.
autre représentation
TÈlÈviseur
+
+
+
+
+
•
marque
alimentation
ampli
niveauSon
etc...
:
:
:
:
:
String
Alimentation
Ampli
int
int
<<interface>>
UsagesGrandPublicDuTÈlÈviseur
TÈlÈcommande
<<rÈalise>>
+
+
+
+
mettreEnMarche ()
arrÍ ter ()
monterSon ()
: int
baisserSon ()
: int
1
mettreEnMarche ()
arrÍ ter ()
monterSon ()
: int
baisserSon ()
: int
etc... ()
Le « use » est en réalité une composition.
autre représentation
usagesGrandPublic
Téléviseur
-
marque
alimentation
ampli
niveauSon
etc...
+
+
+
+
+
mettreEnMarche ()
arrêter ()
monterSon ()
: int
baisserSon ()
: int
etc... ()
Télécommade
: String
: Alimentation
: Ampli
: int
: int
•
Le cercle correspond à la classe interface
•
Le lien entre le téléviseur et le cercle correspond à la réalisation de l’interface.
•
Le lien avec le demi-cercle correspond à un lien d’utilisation entre classe qui spécifie
l’utilisation d’une interface.
UML – Approche objet - introduction – page 28/51 - Bertrand LIAUDET
Un deuxième usage de l’interface
La télévision peut aussi être commandé via son panneau de commandes intégré au poste.
Le modèle devient alors :
usagesGrandPublic
TÈlÈviseur
+
+
+
+
+
marque
alimentation
ampli
niveauSon
etc...
:
:
:
:
:
TÈlÈcommande
String
Alimentation
Ampli
int
int
mettreEnMarche ()
arrÍ ter ()
monterSon ()
: int
baisserSon ()
: int
etc... ()
Panneau de commande
L’intérêt est donc de bien dissocier, dans la conception, la partie interface utilisateur de la
partie objets du système.
interface utilisée
Si on ajoute les interfaces utilisées par le téléviseur, à savoir un cable, une antenne et une prise
électrique, on obtient le modèle suivant :
usagesGrandPublic
Télécommade
Téléviseur
-
marque
alimentation
ampli
niveauSon
etc...
: String
: Alimentation
: Ampli
: int
: int
+
+
+
+
+
mettreEnMarche ()
arrêter ()
monterSon ()
: int
baisserSon ()
: int
etc... ()
cable
antenne
prise
électrique
Conception par les interfaces
Pour trouver les interfaces du système, il faut examiner toutes les paires : utilisateur – usage
du système. On a intérêt à créer dans un premier temps au moins une classe interface par
usage.
UML – Approche objet - introduction – page 29/51 - Bertrand LIAUDET
Les interfaces se trouvent à un haut niveau d’abstraction. On commence par renseigner les
besoins en interfaces utilisateur sans les implémenter. Ces classes seront affinées au fur et à
mesure.
UML – Approche objet - introduction – page 30/51 - Bertrand LIAUDET
5.
Composant logiciel
Présentation
Modularité, abstraction et encapsulation permettent de construire des composants logiciels
réutilisables pouvant aller d’un simple bouton à une application toute entière comme un
traitement de texte.
Deux types de modularité
La modularité dynamique : l’objet
ü Un objet est un module cohérent regroupant des données et des opérations.
ü Ces modules sont créés dynamiquement et peuvent être passés en paramètre.
ü Par l’intermédiaire du nom, on a accès aux opérations.
Exemple : un objet polynôme aura deux opérations : calculerRacines( ) et afficherRacines( )
La modularité statique : le package
L’architecture logicielle va consister à regrouper les classes dans des modules (les packages).
C’est la modularité statique.
Abstraction
L’abstraction permet d’utiliser un objet général sans se préoccuper des différences et des
spécialisations entre différents types de cet objet. Seul le concept général est utilisé ce qui
revient à abstraire les différences.
Exemple : 3 objets de type voiture : break, berline et coupé, auront chacun des méthodes
démarrer( ), couperContact( ), etc. Un utilisateur pourra utiliser un objet voiture sans se
préoccuper des différences de nature entre les voitures.
Encapsulation
L’objet cache la plupart de ses caractéristiques à ses utilisateurs. Les données de l’objet sont
cachées. Seules les spécifications (en-tête) des opérations dites publiques sont visibles des
utilisateurs. On retrouve là la distinction entre fonctionnel et organique (le quoi et le
comment, l’externe et l’interne, le visible et le caché).
Les spécifications sont simplifiées car tous les paramètres correspondant à des données de
l’objet étant cachés, il n’est pas nécessaire de les préciser.
Les données modifiées par les opérations sont gardées dans la mémoire de l’objet.
UML – Approche objet - introduction – page 31/51 - Bertrand LIAUDET
Exemple : un objet adhérent avec 4 opérations publiques : envoyer(unCourrier : Courrier),
afficher(), mettreAJourDossier(), recevoir(unCourrier : Courrier). L’opération afficher permet
de consulter les donnée de l’adhérent. L’opération mettreAJourDossier permet de modifier les
données de l’adhérent.
Exemple
On traite le bloc d’alimentation comme un composant à part :
<<interface>>
<<interface>>
I_TÈlÈviseur_Utilisateur
I_Alim
+
+
+
+
+ Èteindre () : boolean
+ allumer () : boolean
1
alim
allumer ()
Èteindre ()
monterSon ()
baisserSon ()
:
:
:
:
boolean
boolean
int
int
<<rÈalise>>
<<rÈalise>>
<<use>>
TÈlÈviseur
Alim
- allumÈ : boolean
= false
+ <<Implement>> eteindre () : boolean
+ <<Implement>> allumer () : boolean
- marque
: String
- ampli
: Ampli
- niveauSon : int
+
+
+
+
+
<<Implement>>
<<Implement>>
<<Implement>>
<<Implement>>
<<Constructor>>
allumer ()
eteindre ()
monterSon ()
baisserSon ()
Televiseur ()
TÈlÈcommande
:
:
:
:
boolean
boolean
int
int
La classe « Alimentation » réalise deux méthodes d’interface. Le téléviseur accède à la classe
Alimentation par son interface qu’il utilise en tant que composant logiciel.
Concrètement, le constructeur de la classe « Téléviseur » instancie un objet « Alim » qu’on
associe à l’attribut « alim ».
Code Java du constructeur :
public Televiseur() {
alim= (IAlimentation) new Alim();
alim.allumer();
}
De ce fait, il existe une dépendance de type « use » entre le téléviseur et l’ampli.
C’est le même principe entre la télécommande et l’ampli.
On pourrait donc avoir le diagramme de classes suivant :
UML – Approche objet - introduction – page 32/51 - Bertrand LIAUDET
<<interface>>
<<interface>>
I_TÈlÈviseur_Utilisateur
I_Alim
+
+
+
+
+ Èteindre () : boolean
+ allumer () : boolean
1
alim
allumer ()
Èteindre ()
monterSon ()
baisserSon ()
:
:
:
:
boolean
boolean
int
int
<<rÈalise>>
<<rÈalise>>
<<use>>
TÈlÈviseur
Alim
- allumÈ : boolean
- marque
: String
- ampli
: Ampli
- niveauSon : int
= false
+ <<Implement>> eteindre () : boolean
+ <<Implement>> allumer () : boolean
+
+
+
+
+
<<Implement>>
<<Implement>>
<<Implement>>
<<Implement>>
<<Constructor>>
TÈlÈcommande
allumer ()
eteindre ()
monterSon ()
baisserSon ()
Televiseur ()
:
:
:
:
boolean
boolean
int
int
<<use>>
<<use>>
Toutefois, on évite, en général, de mettre les relations de dépendance autres que celles des
interfaces.
A noter aussi que les schémas précédents sont équivalents à :
<<interface>>
<<interface>>
I_TÈlÈviseur_Utilisateur
I_Alim
+
+
+
+
+ Èteindre () : boolean
+ allumer () : boolean
allumer ()
Èteindre ()
monterSon ()
baisserSon ()
:
:
:
:
boolean
boolean
int
int
<<rÈalise>>
<<rÈalise>>
TÈlÈviseur
Alim
- allumÈ : boolean
= false
+ <<Implement>> eteindre () : boolean
+ <<Implement>> allumer () : boolean
1
alim
- marque
: String
- ampli
: Ampli
- niveauSon : int
+
+
+
+
+
<<Implement>>
<<Implement>>
<<Implement>>
<<Implement>>
<<Constructor>>
allumer ()
eteindre ()
monterSon ()
baisserSon ()
Televiseur ()
<<use>>
:
:
:
:
boolean
boolean
int
int
Toutefois, on préfèrera la première version pour des raisons de lisibilité.
UML – Approche objet - introduction – page 33/51 - Bertrand LIAUDET
TÈlÈcommande
6.
L’objet
Définition
Un objet est un exemplaire d’une classe.
Principes techniques
Déclaration
Pour pouvoir utiliser un objet, c’est-à-dire utiliser une de ses opérations publiques, il faut le
déclarer une variable ayant comme type la classe de l’objet en question. Techniquement, la
déclaration d’un objet est toujours la déclaration d’un pointeur sur un objet. La déclaration ne
crée pas l’objet mais seulement le pointeur vers un futur objet.
Construction
On distingue donc entre déclaration et construction de l’objet. La construction s’effectue par
l’opérateur « new » qui va allouer dynamiquement un objet et renvoyer l’adresse de cette
allocation, adresse qui sera affectée à une variable ayant comme type la classe de l’objet en
question.
Comme toute variable allouée dynamiquement, l’objet n’a donc pas à proprement parler de
nom. Quand on déclare un objet, le nom de la variable est le nom du pointeur qui permet
d’accéder à l’objet. Le pointeur pourra référencer un autre objet : on peut donc changer d’objet
sans changer de variable.
Initialisation
Un objet peut être initialisée lors de sa construction, via des opérations particulières appelées
« constructeurs ».
En conception, la construction-initialisation n’est pas abordée. C’est cependant un élément
centrale de la programmation.
Lieux de déclaration – construction des objets
La déclaration et la construction d’un objet peut se faire à deux endroits différents :
ü Au niveau des attributs d’une classe
ü Au niveau d’une variable locale d’une opération
Provenance des objets d’une méthode
Un objet, dans le corps d’une méthode, provient de trois lieux :
UML – Approche objet - introduction – page 34/51 - Bertrand LIAUDET
ü C’est un attribut de l’objet de la méthode : il a été construit avec l’objet.
ü C’est une variable locale à la méthode : il est construit dans la méthode.
ü C’est un paramètre formel de la méthode : il a été fournit par la fonction appelante.
Toutefois, en dernière analyse, on retombera sur les deux premiers cas.
•
Ce dernier cas fait que : si un objet d’une classe 1 fait appel à une opération dont un
paramètre est un objet d’une classe 2 alors la classe 1 dépend de la classe 2.
Syntaxe UML
Les objets sont soulignés et placés dans un rectangle. Le nom de l’objet commence par une
minuscule. Le nom de la classe commence par un majuscule.
Objets nommés :
olivier
Objets sans noms : : Eleve
7.
bertrand
: Professeur
La communication entre les objets : envoi de message
Principe général de l’envoi de message
Envoyer un message à un objet c’est utiliser une de ses opérations.
Un objet 1 envoi un message à un objet 2 quand une opération de l’objet 1 utilise une opération
de l’objet 2.
Pour cela, l’objet 2 doit exister dans l’environnement de l’opération appelante de l’objet 1 :
•
soit c’est une variable locale de l’opération 1,
•
soit c’est un objet passé en paramètre de l’opération 1,
•
soit c’est un attribut de l’objet 1.
Envoi de message et héritage
En programmation objet, la manière d’associer du code à un message est un mécanisme
dynamique qui n’est pas établi à la compilation. Autrement dit, l’envoi d’un message ne
correspond pas à un débranchement vers une adresse de code prédéfinie comme c’est le
cas en programmation procédurale classique. C’est la relation d’héritage entre classes qui
permet de gérer ce mécanisme.
Syntaxe UML du diagramme de séquence
Un expéditeur
Un destinataire
UML – Approche objet - introduction – page 35/51 - Bertrand LIAUDET
Envoi simple
retour implicite
UML – Approche objet - introduction – page 36/51 - Bertrand LIAUDET
8.
Exemple complet : la bibliothèque
Cahier des charges
On considère l’exemple d’une bibliothèque. On considère 2 usages : l’emprunt de livres et le
retour d’un livre.
Pour emprunter un ou plusieurs livres, l’adhérent se sert dans les rayonnages, puis donne sa
carte au bibliothécaire qui l’identifie. Ensuite, l’adhérent donne ses livres au bibliothécaire qui
les identifie. Ensuite, le bibliothécaire redonne la carte et les livres à l’adhérent. L’adhérent ne
peut pas emprunter plus de 3 livres en même temps. Les livres ne doivent pas être emprunter
plus de 14 jours. En cas de retard d’un livre, l’adhérent ne peut plus emprunter d’autres livres.
Pour rendre un livre, n’importe qui donne le livre au bibliothécaire qui l’identifie.
Analyse des interfaces
Pour trouver les interfaces du système, il faut examiner toutes les paires : utilisateur – usage
du système.
L’utilisateur, c’est le bibliothécaire. Il y a deux usages :
•
rendreLivre( ). Pour cela, il suffit d’identifier le livre à rendre.
•
emprunterLivre( ). Pour cela, il faut commencer par identifier l’adhérent pour ensuite
identifier le livre à emprunter.
•
Ces usages sont des méthodes de la classe Livre. On rend quoi : un livre. On emprunte
quoi : un livre. Ces usages caractérisent l’objet livre.
•
•
<<interface>>
UsagesAdhÈrents
+ emprunterLivre (Adherent adhÈrent) : LivreEmprunte
+ rendreLivre ()
<<rÈallise>>
<<use>>
Livre
Ecran
•
- numLivre : int
- titre
: string
- auteur
: string
+ emprunterLivre (Adherent adherent) : LivreEmprunte
+ rendreLivre ()
+ identifierLivre ()
Remarque :
UML – Approche objet - introduction – page 37/51 - Bertrand LIAUDET
Les paramètres des méthodes seront découverts avec l’analyse du diagramme de séquence.
UML – Approche objet - introduction – page 38/51 - Bertrand LIAUDET
Analyse des écrans
On a intérêt à imaginer les écrans pour concrétiser le système :
Ecran « enregistrerUnRetour( )
Identifier Livre :
OK
Info Adhérent
Nom
Prenom
Etc
Livres empruntés
Id, Titre, auteur, Date emprunt, date retour max, nb jours de retard
Id, Titre, auteur, Date emprunt, date retour max, nb jours de retard
On saisie l’id du livre et on valide. On récupère les infos sur l’adhérent et les livres en cours
d’emprunt.
Ecran « enregistrerDesEmprunts( )
Identifier Adhérent :
OK
Info Adhérent
Nom
Prenom
Etc
Livres empruntés
Id, Titre, auteur, Date emprunt, date retour max, nb jours de retard
Id, Titre, auteur, Date emprunt, date retour max, nb jours de retard
Identifier Livre :
OK
On saisie l’id de l’adhérent et on valide. On récupère les infos de l’adhérent. On saisie l’id du livre et
on valide. La liste des emprunts de l’adhérent est mise à jour.
UML – Approche objet - introduction – page 39/51 - Bertrand LIAUDET
Analyse des scénarios
Scénario d’emprunt d’un livre (diagramme de séquence) :
Ècran
BD
BibliothÈcaire
ecranDeGestionDesEmprunts
lire Id AdhÈrent
new (id Adherent)
:AdhÈrent
identifierAdhÈrent(id AdhÈrent)
select adhÈrent
infos adhÈrent
select emprunts
liste des emprunts
new
:LivreEmpruntÈ
ajoutLivreEmpruntÈ(:LivreEmpruntÈ)
afficherAdhÈrent( )
lire Id Livre
new (id livre)
new:LivreEmpruntÈ
emprunterLivre(adhÈrent)
select livre
update emprunts
new:LivreEmpruntÈ
ajoutLivreEmpruntÈ(new:LivreEmpruntÈ)
afficherAdhÈrent( )
delete
delete
delete
Remarques :
•
On crée un pseudo objet écran qui nous permet de clarifier l’interface avec l’utilisateur, et un
pseudo objet « BD » pour clarifier l’interface avec la BD. Ces objet n’apparaîtront pas dans le
diagramme de classes.
UML – Approche objet - introduction – page 40/51 - Bertrand LIAUDET
•
Les objets « :Adhérent », « :LivreEmprunté » et « new:LivreEmprunté » sont détruits à la sortie
de la méthode « EnregistrerDesEmprunts »
•
La méthode « identifierAdhérent » pourrait être intégré dans le constructeur de l’adhérent et ne
pas être détaillée au niveau du diagramme de séquence.
UML – Approche objet - introduction – page 41/51 - Bertrand LIAUDET
Diagramme des classes
Livre
- numLivre : int
- titre
: string
- auteur
: string
+ emprunterLivre (Adherent adherent) : LivreEmprunte
+ rendreLivre ()
+ identifierLivre ()
AdhÈrent
- numAdhÈrent : int
- nom
: string
LivreEmpruntÈ
3
+ ajoutLivreEmpruntÈ (LivreEmprunte livreEmpruntÈ)
+ afficherAdhÈrent ()
+ identifierAdhÈrent ()
- dateEmprunt
: date
- dateRetourAttendue : date
- retard
: int
Remarques :
On met 3 pour le nombre de livres empruntés par l’adhérent pour obtenir un tableau 3 livres
empruntés dans la table des adhérents.
Le livre emprunté est une espèce de livre : il hérite des attributs et des méthodes du lives et porte des
attributs supplémentaires. A noter qu’on devrait descendre la méthode : « emprunterLivre » au niveau
de la classe « LivreEmprunté »
UML – Approche objet - introduction – page 42/51 - Bertrand LIAUDET
9.
Diagramme de classes et base de données : les classes « métier ».
Classes-métier et classes organiques
On distingue entre classe « métier » et classe organique.
Les classes-métier sont celles qui correspondent directement au métier de l’application traitée
tandis que les classes organiques sont des classes plus techniques.
Les classes-métier correspondent reprennent grosso modo le modèle conceptuel des données
(le MCD).
Elles permettent une première approche du système.
Classes-métier et base de données
On peut utiliser le MCD ou les tables de la base de données pour commencer à réaliser un
diagramme de classes-métier.
Relations entre le modèle BD et le modèle objet
MEA
ADHERENTS
NA
nom
adr
tel
0,n
EMPRUNTER
LIVRES
0,n
NL
Èditeur
datEmp
durÈeMax
datRet
1,1
correspond ‡
OEUVRES
N0
auteur
titre
0,n
UML
UML – Approche objet - introduction – page 43/51 - Bertrand LIAUDET
EMPRUNTER
OEUVRES
+ datEmp
: java.util.Date
+ durÈeMax : java.util.Date
+ datRet
: java.util.Date
+ N0
: int
+ auteur : java.lang.String
+ titre
: java.lang.String
1..1
ADHERENTS
+
+
+
+
NA
nom
adr
tel
:
:
:
:
double
java.lang.String
java.lang.String
java.lang.String
0..*
LIVRES
0..*
0..*
+ NL
: int
+ Èditeur : int
Explications de technique UML
•
Tous les attributs sont « + » c’est-à-dire public. En réalité, ils devraient passer « - » , c’està-dire privés. Il faut donc faire attention aux résultats des traductions automatiques !
•
En UML, on ne peut pas mettre d’attributs sur les associations. Les associations non
hiérarchiques avec attributs du MEA donnent lieu dans le modèle de BD UML à des
classes-associations.
•
Une classe-association est une association classique à laquelle est raccrochée une classe
dont les attributs proviennent de l’association non hiérarchique du MEA.
Explications sur la modélisation
•
Les classes « livres » et « oeuvres » ont été fusionnées. Au niveau de l’application, leur
distinction est inutile.
•
La classe association « emprunter » devient une simple classe : « LivreEmprunté » : ça
permet de gérer plus finement les cardinalités et les navigabilités.
•
Les navigabilités sont limités à « Adhérent » vers « LivreEmprunté » et « LivreEmprunté »
vers « Livre ». Cela suffit gérer les usages.
•
L’association entre « LivreEmprunté » et « Livre » est une composition : on aura un attribut
de type « Livre » dans la classe « LivreEmprunté ».
•
L’association entre « Adhérent » et « LivreEmprunté » est de cardinalité 3 : on aura attribut
livreEmrunte qui sera un tableau de 3 « LivreEmprunté ». On n’a besoin que de ça.
•
On a ajouter la classe « Bibliothécaire » qui porte les méthodes de l’interface.
•
La classe « Bibliothécaire » utilise la classe « Adhérents »
Remarque générale
On peut partir d’un MCD pour commencer le diagramme des classes. Toutefois, le diagrammes
des classes doit être retravaillé en fonction des usages du système.
UML – Approche objet - introduction – page 44/51 - Bertrand LIAUDET
UML – Approche objet - introduction – page 45/51 - Bertrand LIAUDET
10. L’affichage et les écrans
On peut aussi avoir un modèle qui gère l’affichage au niveau de chaque classe :
Fenetre
EcranAdhÈrent
+ afficherAdhÈrent (int numAdhÈrent, string nom)
<<use>>
AdhÈrent
- numAdhÈrent : int
- nom
: string
+ ajoutLivreEmpruntÈ (LivreEmprunte livreEmpruntÈ)
+ afficherAdherent ()
EcranLivreEmpuntÈ
+ afficherLivreEmpruntÈ ()
<<use>>
LivreEmpruntÈ
- dateEmprunt
: date
- dateRetourAttendue : date
- retard
: int
+ afficherLivreEmpruntÈ () : int
1
Livre
- numLivre : int
- titre
: string
- auteur
: string
Avec un tel modèle, la notion d’interface est toujours utile pour présenter les services rendus
par le système, mais ne sert plus à dissocier le calcul de l’interface utilisateur.
A noter que dans un diagramme de classes global, on évitera la présentation des fenêtres et des
écrans.
UML – Approche objet - introduction – page 46/51 - Bertrand LIAUDET
11. La gestion des collections
Quand on a des collections (ici le tableau des 3 livres empruntés), il peut y avoir des
traitements qui s’appliquent à toute la collection. Dans notre exemple, les adhérents pourrait
appliquer des traitement à tous leurs livres empruntés. Par exemple, on pourrait vouloir ajouter
une semaine de délai à tous les livres empruntés d’un adhérent
Le modèle devient le suivant :
AdhÈrent
- numAdhÈrent : int
- nom
: string
LivreEmpruntÈ
3
+ ajoutLivreEmpruntÈ (LivreEmprunte livreEmpruntÈ)
+ retarderLesDatesRetour (int nbJours)
- dateEmprunt
: date
- dateRetourAttendue : date
- retard
: int
+ retarderDateRetour (int nbJours)
1
Livre
- numLivre : int
- titre
: string
- auteur
: string
L’algorithme de « retarderLesDatesRetour » est
Pour i de 1 à 3
LivreEmprunté[i].retarderDateRetour(nbJours)
Fin pour
Pour généraliser le traitement, c’est-à-dire éviter que la boucle de traitement soit dans la classe
appelante « Adhérent », on définit une classe « plurielle » ou « collection » :
« LivesEmpuntés ». C’est cette classe qui fera le traitement alors que la classe adhérent ne fera
qu’appeler la méthode de la classe plurielle. Ainsi le traitement sera accessible à n’importe
quelle autre classe.
Le modèle devient le suivant :
LivreEmpruntÈ
AdhÈrent
- numAdhÈrent : int
- nom
: string
- dateEmprunt
: date
- dateRetourAttendue : date
- retard
: int
+ retarderLesDatesRetour (int nbJours)
+ retarderDateRetour (int nbJours)
1
1
<<use multiple>>
Livre
LivresEmpruntÈs
+ retarderDateRetour (int nbjours)
+ ajoutLivreEmpruntÈ (LivreEmprunte livreEmpruntÈ)
- numLivre : int
- titre
: string
- auteur
: string
UML – Approche objet - introduction – page 47/51 - Bertrand LIAUDET
Les itérations sur l’ensemble des livres empruntés ont été encapsulées dans la classe plurielle
« LivresEmpruntés ». La méthode « retarderLesDatesRetour » de « LivresEmpruntés » contient
la boucle.
Algorithme de « retarderLesDatesRetour » : LivresEmpruntés.retarderDateRetour(nbJours)
UML – Approche objet - introduction – page 48/51 - Bertrand LIAUDET
12. Les 3 relations fondamentales entre les objets (et les classes) : composition,
utilisation, héritage
Il y a trois types de relations entre les objets : la composition, l’utilisation et l’héritage.
Ces trois relations sont aussi les trois relations fondamentales entre les classe
Ces relations génèrent des dépendances entre les objets.
La composition
Un objet 2 est composant d’un objet 1 si c’est un attribut de l’objet 1.
La relation de composition génère une dépendance : l’objet 1 dépend de l’objet 2.
TÈlÈviseur
- marque : string
- etc...
: int
+ etc... ()
1
ampli
Ampli
1
Alimentation
Alimentation
- niveauSon : int
+ monterSon () : int
+ baisserSon ()
+ mettreEnMarche ()
+ arrÍ ter ()
L’utilisation (ou dépenndance)
Un objet 2 est utilisé par l’objet 1 si il est déclaré localement dans une opération d’un objet 1
ou passé en paramètre formel d’une opération d’un objet 1.
La relation d’utilisation génère une dépendance : l’objet 1 dépend de l’objet 2.
UML – Approche objet - introduction – page 49/51 - Bertrand LIAUDET
BibliothÈcaire
+
+
-
enregistrerDesEmprunts ()
enregistrerUnRetour ()
identifierAdherent (int numAdherent)
identifierLivre (int numLivre)
<<use>>
:
:
:
:
void
void
Adherent
Livre
<<use>>
Livre
AdhÈrent
- numAdhÈrent : int
- nom
: string
+ ajoutLivreEmpruntÈ (LivreEmprunte livreEmpruntÈ) : void
- numLivre : int
- titre
: string
- auteur
: string
L’héritage
Une classe peut hériter des attributs et des opérations d’une autre classe. La classe
héritière est appelée sous-classe, la classe dont elle hérite est appelée classe parente. Une
classe parente peut à son tour hériter. Si une classe a une seule classe parente, on parle
d’héritage simple sinon d’héritage multiple.
Héritage d’attributs : l’ensemble des attributs d’un objet d’une classe est constitué de
l’ensemble de ses attributs et de l’ensemble des attributs de ses classes parentes.
En ce sens, l’héritage est une façon d’organiser les concepts dans un rapport d’espèce à
genre : l’espèce (sous-classe) est une sorte du genre (classe parente).
Héritage d’opérations : l’ensemble des opérations applicables à un objet est constitué de
l’ensemble de ses opérations et de l’ensemble des opérations de ses classes parentes.
En ce sens l’héritage est une technique de partage et de réutilisation du code existant.
La manière d’associer du code à un message est un mécanisme dynamique qui n’est pas établi à
la compilation. L’envoi d’un message ne correspond pas à un débranchement vers une adresse
de code prédéfinie comme c’est le cas en programmation procédurale classique. La
programmation objet permet de trouver dans la hiérarchie des classes, le code du message à
exécuter.
L’algorithme qui permet d’associer du code à un message peut donc être vu ainsi :
ExecRécursif (message, classe)
Si ilExiste (message, classe)
Exectuer (message, classe)
Return
Finsi
Si parent (classe) = null
Afficher (« erreur »)
Return
Finsi
UML – Approche objet - introduction – page 50/51 - Bertrand LIAUDET
ExecRécursif (message, parent (classe) )
Fin
Formalisme UML
Fenetre
EcranAdhÈrent
•
+ afficherAdhÈrent (int numAdhÈrent, string nom)
EcranLivreEmpuntÈ
+ afficherLivreEmpruntÈ ()
UML – Approche objet - introduction – page 51/51 - Bertrand LIAUDET
Téléchargement