Cours de Génie Logiciel à Batna II
Cours de Génie Logiciel à Batna II
Département Informatique
Support de cours :
Génie logiciel
0. Introduction
0.1 Description du cours ................................................................................................... 1
0.2 Objectifs du cours ...................................................................................................... 4
1. Chapitre I : Analyse des besoins et définition du problème
1.1 Introduction ............................................................................................................... 5
1.2 Définition du problème................................................................................................ 6
1.3 Grilles de Levesques ................................................................................................... 7
1.3.1 Application des Grilles de Levesque ..................................................................... 8
1.4 Délimitation du périmètre du système ........................................................................ 9
2. Chapitre II : Digramme de cas d’utilisation
2.1 Introduction ............................................................................................................. 10
2.2 Éléments graphiques d’un diagramme de cas d’utilisation ........................................ 10
2.3 Formalisme de diagramme de cas d’utilisation .......................................................... 11
2.3.1 Identifier les acteurs .......................................................................................... 11
2.3.2 formaliser les cas d’utilisation .......................................................................... 12
2.4 Relations et stéréotypes dans le diagramme de cas d’utilisation ............................... 13
2.4.1 Relation d’include ............................................................................................ 13
2.4.2 Relation Extends .............................................................................................. 14
2.4.3 Relation d’héritage (généralisation et spécialisation) ........................................ 15
2.5 Rédaction de cas d’utilisation selon le Formlulaire de Cockburn ............................... 16
2.5.1 Rubriques de Cockburn...................................................................................... 16
2.5.2 Exemple Domaine ............................................................................................ 17
2.6 Conclusion ................................................................................................................. 18
3. Diagramme d’activité
3.1 Introduction ............................................................................................................. 19
3.2 Eléments graphiques de diagramme d’activité .......................................................... 19
3.3 Formalisme d’un diagramme d’activité ..................................................................... 21
3.4 Flot de contrôle et synchronisation dans le diagramme d’activité ............................. 23
3.4.1 Synchronisation disjonctive (embranchement) ................................................ 23
3.4.2 Synchronisation conjonctive (conjonction) ....................................................... 24
3.4.3 Les couloirs dans le diagramme d’activité ........................................................ 25
3.4.4 Flux d’objet ............................................................................................................ 26
3.5 Conclusion ................................................................................................................. 28
4. Chapitre IV : Diagramme de classes
4.1 Introduction ............................................................................................................. 29
4.2 Éléments graphiques d’un diagramme de classes...................................................... 29
4.3 Formalisme d’un diagramme de classes ................................................................... 31
4.3.1 La multiplicité ................................................................................................. 31
4.3.2 Notion d’association ........................................................................................ 32
4.3.3 Association binaire et n-aire ............................................................................ 32
4.3.4 Association avec navigabilité et contraintes ..................................................... 33
4.3.5 Association dérivée .......................................................................................... 34
4.3.6 Classe-Association ........................................................................................... 35
4.4. Relations dans le diagramme de classes ................................................................... 36
4.4.1 Relation d’agrégation et de composition ......................................................... 36
4.4.2 Relation de dépendance ................................................................................. 37
4.4.3 Relation d’Héritage, généralisation et spécialisation ...................................... 37
4.5 Conclusion ................................................................................................................ 38
5. Chapitre V : Diagramme d’objets
5.1 Introduction ............................................................................................................. 39
5.2 Éléments graphiques d’un diagramme d’objets ....................................................... 39
5.3 Formalisme d’un diagramme d’objets ...................................................................... 40
5.3.1 Constructeur et destructeur d’objets .............................................................. 40
5.3.2 Durée de vie d’un Objet .................................................................................. 40
5.3.3 Objet Composite ............................................................................................. 41
5.3.4 Les contraintes dans le diagramme d’objets .................................................... 41
5.3.5 Le langage de contrainte OCL ......................................................................... 43
5.4 Implémentation en java ............................................................................................ 44
5.4.1 Implémentation de la relation bidirectionnelle 1-1.......................................... 45
5.4.2 Implémentation de la relation bidirectionnelle 1-N .......................................... 46
5.4.3 Implémentation de la relation unidirectionnelle 1-N ........................................ 46
5.4.4 Implémentation de la relation unidirectionnelle 1-1 ........................................ 47
5.5 Conclusion ................................................................................................................. 47
Introduction
Introduction
Il est certain qu’un processus de conception vise en premier lieu l’obtention d’une solution
dîtes acceptable du système informatique. Par analogie avec un architecte qui dessine
plusieurs plans pour arriver au plan final d’architecture de la maison, la conception d’un
système informatique est organisée dans un processus de modélisation qui prévoit aussi
plusieurs visions du même problème pour aider à trouver une solution acceptable. Par
conséquent, la solution finalement retenue n’est guerre obtenue en une seule itération.
Plusieurs étapes sont nécessaires pour raffiner le niveau de détails du système à réaliser. Les
premières étapes donnent une vision macro à très gros grains et permettent d’avancer dans
la compréhension du problème.
Un modèle est une abstraction de la réalité qui permet de présenter une ou plusieurs vues
sur le système ; la vue a pour objet d’aider le concepteur à mieux comprendre et donc mieux
maîtriser le système. La cohérence entre les différentes vues du système est importante,
chaque vue cible des catégories différentes d’intervenants ayant des besoins différents (voir
figure ci-dessous). Il est important de rappeler ici que chaque vue représente une étape dans
le cycle de vie de développement de logiciel. Nous avons abordé le processus de
développement logiciel et les différents modèles de cycle de vie d’un logiciel (Modèle en V,
Modèle en cascade et Modèle en spirale) dans la première partie du module (gestion de
projet de développement de logiciel). Ce cours se contente de présenter les étapes d’analyse
et de conception en se basant sur le langage de modélisation UML.
Les modèles obtenus peuvent être implémentés dans un langage de programmation objet.
On se contente de présenter dans ce cours les 10 principaux diagrammes (figure 0.3), leurs
rôles complémentaires, et montrer comment les diagrammes d’un modèle sont construits
de manière cohérente.
Notons que ces diagrammes peuvent être classés selon leurs aspects et fonctionnement
suivant le point de vue classique de modélisation (statique, fonctionnel et dynamique)
(Roques & Vallée 2003). L’aspect fonctionnel comporte : -les diagrammes de cas d’utilisation, -
de séquence et -d’activité ; l’aspect statique comporte : -les diagrammes de classes,-
paquetage, -objets, -composants et -déploiement ; l’aspect dynamique concerne : -les
diagrammes de séquence,- de communication, -d’activité et -d’états-transitions.
Voici une brève description du contenu de chaque type de diagramme présenté dans la
figure ci-dessus :
Cas d’utilisation: c’est un diagramme visualisant les interactions entre le système et les
utilisateurs (et autres systèmes externes). Il aide dans la visualisation des exigences / besoins
;
Activité : il permet la modélisation des processus métier avec les échanges de données ;
Classes : Ce diagramme permet de présenter les classes (d’analyse et de conception), les
types, les interfaces et relations entre eux ;
Objets : on présente dans ce diagramme les instances de classes définissant une
configuration importante du système ;
Machine à états ou états-transitions: il s’agit de définir les états des classes à travers leur
cycle de vie (de la création / instanciation des objets à leur destruction) et les événements
qui provoquent les transitions / changements d’états ;
Interaction : on distingue deux types de diagrammes d’interaction :
- séquence : ce type de diagramme permet de visualiser en plus des interactions leur
ordre d’exécution qui est considéré comme important;
- communication : on visualise dans ce diagramme les interactions entre objets pour
lesquels les connexions entre objets sont importantes ;
Composants : il s’agit de rassembler des classes ou des composants tels que conçus par
l’équipe de développement pour décomposer le système en parties de logiciel gérables;
Déploiement : il concerne les unités de configuration, d’installation et de déploiement du
produit fini sur un parc de machines.
Paquetages : on rassemble dans ce type de diagramme les éléments de modélisation par
exemple pour les distribuer entre membres de l’équipe de développement ;
Le langage UML possède quelques autres diagrammes qui ne seront pas détaillés dans ce
cours : diagrammes de temps (en anglais, timing), diagrammes de vues globales
d’interactions (en anglais, interaction overview) et diagrammes de structures composites.
L’utilisation des 10 principaux diagrammes, qui seront présentés dans ce cours, sera
largement suffisant aux étudiants de se familiariser avec les concepts liés à la modélisation
informatique et atteindre les objectifs de ce cours.
L’objectif de ce cours est double: il s’agit d’une part de permettre aux étudiants d’avoir une
vision globale sur l’analyse et la conception des systèmes informatiques afin d’apprendre la
manière d’abstraire la réalité pour mieux comprendre le système à réaliser. D’autre part ce
cours permet l’étude du langage de modélisation Uml en présentant les éléments
méthodologiques d’utilisation des différents types de diagrammes dans un processus de
modélisation.
A la fin de ce cours l’étudiant sera capable de
- Se familiariser avec les concepts liés aux démarches de l’analyse, de conception et de
développement des systèmes informatiques;
- Savoir traduire un besoin fonctionnel en s'appuyant sur les diagrammes UML ;
- Comprendre la représentation et l'intérêt d'utilisation des différents diagrammes
UML pour le développement d’un logiciel ;
- Intégrer les concepts objets nécessaires à une analyse/conception ;
- Maîtriser les 10 principaux diagrammes UML.
Chapitre I :
1.1 Introduction
Le maître d’œuvre est par exemple la société de services en ingénierie informatique (SSII ou
SS2I), qui est une société de services spécialisée en génie informatique. Elle se caractérise
par ses compétences techniques de maîtrise d'œuvre. Le maître d’œuvre est souvent choisi
pour ses compétences techniques, mais aussi pour son savoir faire. Au début du projet, un
maître d’œuvre est capable de recueillir les besoins auprès des maîtres d’ouvrage. Le recueil
des besoins implique une bonne compréhension du métier : par exemple la réalisation d’un
logiciel pour une banque nécessite des connaissances approfondies dans les systèmes
bancaires pour intégrer toutes les contraintes et les exigences du métier. Cette condition est
primordiale pour bien cerner les cas d’utilisation exprimés par le client afin d’apporter des
solutions adéquates (Charroux et al 2005).
Le problème souvent posé pendant la première étape concerne la distinction entre les
besoins, les objectifs et les opportunités. La question qui se pose est : ai-je toutes les
connaissances et les informations pour définir ce que doit faire le système ?
Le recueil de besoin nécessite de compléter le cahier des charges par des discussions
approfondies avec le maître d’ouvrage et les futurs utilisateurs du système. Le premier
problème posé au niveau de la phase d’analyse est celui de communication. Une expression
de besoin n’est pas facile car elle nécessite des compétences pluridisciplinaires pour assurer
une maitrise des concepts liés aux domaines différents.
« Je sais que tu crois avoir compris ce que tu penses que j’ai dit, mais je ne suis pas sûr que
tu réalises que ce que tu as entendu n’était pas ce que je voulais dire. »
Le problème d’expression de besoin présente toujours des difficultés autant pour les
informaticiens que non informaticiens. L’image d’humour très connue par les chefs de
projets présente le problème réel et comment peut-on exprimer les besoins et livrer ce que
le client a mal décrit.
Cette section présente une grille d’analyse appelée Grille de Levesque qui peut être utilisée
comme un outil pouvant guider le concepteur à définir le problème. L’idée consiste à trouver
un seul objectif au projet. Il s’agit de classer chaque affirmation pertinente issue des
réunions de travail (brain-storming) ou d’une entrevue avec le client. En analysant les
informations collectées, il faut d’abord procéder par la distinction de 6 classes de faits :
Besoins, Objectif, Symptôme, Problème, Solution et Opportunité. Il faut donc distinguer un
symptôme de problème, un besoin d’un objectif et une solution d’une opportunité. Nous
donnons dans ce qui suit la définition de chaque concept :
Exemples :
Exemples :
Exemples :
Exemple
Exercice : proposer une autre solution en mettant « (L) : augmenter les revenus » comme un
objectif.
1.4 Délimitation du périmètre du système
La délimitation du système nécessite une analyse de sa structure ainsi que son intégration
dans un système supérieur. La délimitation concerne tout simplement le fait de mettre des
limites au système par le fait de spécifier les exigences en matière de développement,
d’achat, d’exploitation ou même de maintenance. Il s’agit d’analyser et documenter les
frontières de systèmes et de sous-systèmes en insistant surtout sur la distinction entre les
décisions de conception et les contraintes d’exploitation. Il faut également identifier et
documenter les interfaces entre systèmes et en décrire les interactions.
2.1 Introduction
UML propose de représenter les cas d'utilisation d'un système sous une forme graphique
nommée diagramme de cas d'utilisation appartenant au modèle des besoins. En effet, UML
n’est qu’un langage et il ne sert en première phase de projet qu’à formaliser les besoins,
c'est-à-dire à les représenter sous forme graphique suffisamment simple pour être
compréhensible par les acteurs du projet (Toutes les personnes impliquées dans le projet).
Notons que ces acteurs ne sont pas forcément tous des informaticiens, il leur faut donc un
moyen simple d’exprimer leurs besoins (Gollot 2015). Ceci est le rôle précis du diagramme de
cas d’utilisation : faciliter l’expression des besoins sous forme graphique compréhensible par
toutes les personnes impliquées dans le projet même pour les non informaticiens.
● Un cas d'utilisation est une manière spécifique d’utiliser un système. Le cas d’utilisation
réalise un service de bout en bout, avec un déclenchement, un déroulement et une fin, pour
l’acteur qui l’initie.
● Un acteur est une entité externe au système, en interaction avec ce dernier. L'entité est un
rôle joué par un utilisateur, par exemple un comptable, ou par un autre système, un capteur
par exemple.
Un diagramme de cas d'utilisation montre acteurs et cas d'utilisation ensemble avec leur
relations. La relation entre un acteur et un cas d'utilisation est appelée association et
correspond au fait que l'acteur participe à un cas d'utilisation. Les cas d'utilisation
représentent les fonctionnalités d'un système, ou d'une entité d'un système, telles qu'elles
sont sollicitées en interaction avec des événements extérieurs. Ils donnent une vision
"haute" et dynamique du système.
Acteur : un bonhomme ou une classe stéréotypée <<actor>>. Son rôle est décrit sous ses
pieds.
Cas d'utilisation : une ellipse. Le nom du cas d'utilisation est placé généralement en
dessous de l'ellipse.
Exemple :
Exemple
Regroupe dans une vue synthétique les acteurs et les liens s’ils interagissent avec des cas
d’utilisation. Les cas d’utilisation sont des abstractions du dialogue entre les acteurs et le
système. Ils n’entrent pas dans le détail de chaque scénario.
Gestion de Bibliothèque
Etudiant
UML propose trois types de relations standards entre cas d'utilisation, <<include>> ,
<<extend>> et la relation d’héritage qui peut être considéré comme une relation de
généralisation ou de spécialisation. Les deux premières sont représentées par un stéréotype
de dépendance, l'autre étant la relation de généralisation représentée en UML par une
flèche creuse à pointe fermée.
La relation d’inclusion de deux cas d’utilisation est notée par une dépendance stéréotypée
« «include» ». L’inclusion exprime le fait qu’un cas d’utilisation comprend une séquence
d’actions consécutives qu’il est possible de factoriser avec d’autres cas d’utilisation. Lorsque
le système modélisé atteint une certaine taille, il est important de montrer les relations
d’inclusion qui définissent alors des parties du système réutilisables par d’autres parties.
Par exemple, une opération de retrait et une opération de transfert nécessitent toutes les
deux une opération de vérification de l'identité du client.
Une relation de généralisation d'un cas d'utilisation B vers un cas d'utilisation A signifie que B
est une spécialisation de A. Contrairement aux deux autres relations, la relation de
généralisation n'est pas un stéréotype. Elle indique qu'un cas d'utilisation est une variation
d'un autre.
Par exemple dans le cas d’utilisation "Retirer de l'argent", si il s’agit de retirer de l’argent sur
un compte sur livret le comportement des deux cas d’utilisation peut être tout à fait
différent.
Figure 2.10 Relation de généralisation
Pour rédiger un cas d’utilisation, nous avons besoins de préciser en premier lieu le titre du cas
d’utilisation. Un cas d'utilisation (use case) commence toujours par un verbe décrivant une action.
(Retirer de l’argent, emprunter un livre ….).
Il est ici inutile de préciser tous les processus techniques menant aux actions, il suffit de les modéliser
en langage simple et compréhensible. Les cas d'utilisation seront modélisés par des développeurs
sous forme technique dans une seconde étape. Nous nous référons dans cette partie du cours aux
travaux d’Alistair Cockburn (Cockburn, 2001). L'idée est de fournir un format de présentation
textuelle à la fois simple et riche du cas d’utilisation. Ce formulaire sert comme un guide méthodique
de rédaction de cas d’utilisation. Nous nous basons dans ce qui suit sur l’exemple de système de
gestion de bibliothèque pour montrer comment suivre les rubriques de cockburn afin de les utiliser
prochainement dans les futurs projets.
Résumé: Liste des actions réalisées par un étudiant se présentant pour emprunter un
ouvrage dans la bibliothèque.
Pré-condition(s):
Action de fin:
Post-condition(s):
Exceptions:
Exception B :
- La carte n’est pas valide ou l’étudiant est banni pour quelques jours car il a rendu son
précédent emprunt trop tard.
- précise les causes du refus de prêt
Remarques ergonomiques : on pourra utiliser un lecteur de code barre pour récupérer les
coordonnées de l’ouvrage.
Contraintes non fonctionnelles
2.6 Conclusion
Nous avons présenté dans ce chapitre le diagramme de cas d’utilisation et son importance dans le
recueil, d’analyse et d’organisation des besoins. Nous avons également vu que la description d’un
cas d’utilisation se fait par des scénarios qui définissent la suite logique des actions qui constituent ce
cas. Cette séquence doit être représentée en se basant sur le formulaire de Cockburn. Notons qu’il
est possible de définir des scénarios simples ou des scénarios plus détaillés faisant intervenir les
variantes, les cas d’erreurs, etc.
Il est important de noter ici que la description détaillée des scénarios nécessite une représentation
faisant apparaitre des détailles (conditions, boucle, l’enchainement d’actions de haut niveau…) que le
cas d’utilisation ne les représente pas ; et il faut donc utiliser le diagramme d’activité pour les
représenter. Nous présentons dans le chapitre suivant le diagramme d’activité.
Chapitre III :
Diagramme d’activité
3.1 Introduction
A la différence du cas d’utilisation qui montre ce que fait ou doit faire le système ; Un diagramme
d’activité permet de montrer l’enchaînement des activités d’un système ou même d’une opération.
Le diagramme d’activité représente le flot de contrôle qui retrace le fil d’exécution et qui transite
d’une activité à l’autre dans le système. Dans la pratique, les diagrammes d’activité sont bien adaptés
à cette phase de l’analyse qui consiste en l’expression des processus métier comme un ensemble
d’actions coordonnées pour atteindre un but. Dans ce sens il est comme un organigramme.
L’avantage d’un diagramme d’activité par rapport à un simple organigramme réside dans le fait de
son pouvoir d’expliciter des activités parallèles et leur synchronisation. Le diagramme d’activité est
utilisé surtout pour modéliser un workflow dans un ou plusieurs cas d’utilisation. Le diagramme
d’activité est le plus approprié pour modéliser la dynamique d’une tâche ou d’un groupe de tâches.
Le premier type de losange est appelée une décision et simule le début d’une instruction « si-
alors ». Les conditions sont appelées des gardes. Le second type de losange signifie la fusion des
branches à la fin du « si-alors » (voir l’exemple d’utilisation des losanges dans la figure 3.2). Il faut
penser aux situations de blocage, pour ce fait les conditions doivent être complètes pour éviter que
l’activité ne soit bloquée ou gelée indéfiniment parce qu’aucune des conditions n’est valide.
Exemple :
Une activité débute par un nœud initial représenté par un disque noir. Cette action marque le
début de l’activité et est suivi d’arêtes représentant le passage à l’action suivante. Le nœud
terminal ou final signifiant la fin de l’activité est représentée par un disque noir entouré d’un second
disque. Entre les deux extrémités, les actions importantes du scénario sont reliées entre elles de
façon à montrer le flot de l’activité : les enchaînements ou séquences et la concurrence
(parallélisme).
Les actions sont des étapes discrètes à partir desquelles se construisent les comportements. La
notion d'action est à rapprocher de la notion d'instruction élémentaire d'un langage de
programmation (comme C++ ou Java). Selon (Audibert 2009). Une action peut être, par exemple :
Nous décrivons ci-dessous les types d'actions les plus courants prédéfinis dans la notation UML.
L'action call operation correspond à l'invocation d'une opération sur un objet de manière
synchrone ou asynchrone. Lorsque l'action est exécutée, les paramètres sont transmis à
l'objet cible. Si l'appel est asynchrone, l'action est terminée et les éventuelles valeurs de
retour seront ignorées. Si l'appel est synchrone, l'appelant est bloqué pendant l'exécution
de l'opération et, le cas échéant, les valeurs de retour pourront être réceptionnées.
L'action call behavior est une variante de l'action call operation car elle invoque
directement une activité plutôt qu'une opération.
Il s'agit d'une variante de l'action accept event pour les appels synchrones.
Figure 3.3 Représentation des actions dans le diagramme d’activité (Audibert 2009).
3.4 Flot de contrôle et synchronisation dans le diagramme d’activité
Les actions qui se déroulent en même temps sont dites concurrentes. Elles sont modélisées entre
deux traits épais comme des chemins parallèles. Les séquences d’actions en parallèle débutent en
même temps, sont toutes exécutées, mais par définition ne finissent pas au même instant. La fin de
l’action join intervient lorsque toutes les actions en parallèle se terminent ; join est donc un point de
synchronisation.
Il est possible de synchroniser les transitions à l'aide des "barres de synchronisation". Une barre de
synchronisation permet d'ouvrir et de fermer des branches parallèles au sein d'un flot d'exécution :
- Les transitions qui partent d'une barre de synchronisation ont lieu en même temps.
- On ne franchit une barre de synchronisation qu'après réalisation de toutes les
transitions qui s'y rattachent.
Une jonction est la recomposition du flux de contrôle de deux ou plusieurs flux de contrôle en un
seul.
Les partitions appelées des couloire (Swimlanes en anglais) dans le diagramme d’activité
sont généralement utilisés pour organiser un diagramme d'activités. Il s’agit de définir des
"couloirs d'activités" selon les différents responsables des actions représentées. Les couloirs
sont un genre de paquet pour la responsabilité d'organisation des activités dans une classe.
Un diagramme d'activité peut être divisé visuellement en des lignes solides verticales des
deux côtés. Chaque couloire représente la responsabilité d'une partie de l'activité globale, et
peut par la suite être mis en application par un ou plusieurs objets.
- Les flux d'objets sont représentés par des relations de dépendance entre
objets et états d'action ou d'activités.
- Les flux d'objets sont représentés par des flèches :
Nous avons montré que le diagramme d’activité est utilisé dans la phase de conception afin
d’offrir une description détaillée du diagramme de cas d’utilisation. Le diagramme d’activité
offre une vue centrée sur les traitements. Cette vue permet de modéliser efficacement le
cheminement de flots de contrôle et flots de données. L’objectif n’est pas certes de fixer
complètement le choix d’implémentation, mais de fournir une vision abstraite de
traitement. Par exemple, l’expression de mécanismes concurrents n’implique pas forcément
le fait d’imposer une architecture parallèle spécifique.
Après avoir montré comment concevoir une vue permettant de visualiser les traitements,
nous allons aborder dans le chapitre suivant le diagramme de classes qui montre la structure
interne du système.
Chapitre IV : Diagramme de classes
4.1 Introduction ............................................................................................................. 29
4.2 Éléments graphiques d’un diagramme de classes...................................................... 29
4.3 Formalisme d’un diagramme de classes ................................................................... 31
4.3.1 La multiplicité ................................................................................................. 31
4.3.2 Notion d’association ........................................................................................ 32
4.3.3 Association binaire et n-aire ............................................................................ 32
4.3.4 Association avec navigabilité et contraintes ..................................................... 33
4.3.5 Association dérivée .......................................................................................... 34
4.3.6 Classe-Association ........................................................................................... 35
4.4. Relations dans le diagramme de classes ................................................................... 36
4.4.1 Relation d’agrégation et de composition ......................................................... 36
4.4.2 Relation de dépendance ................................................................................. 37
4.4.3 Relation d’Héritage, généralisation et spécialisation ...................................... 37
4.5 Conclusion ................................................................................................................ 38
Chapitre IV :
Diagramme de classes
4.1 Introduction
Une classe est un concept abstrait représentant des éléments variés comme ( Audibert 2009):
Une classe est un classeur. Elle est représentée par un rectangle divisé en trois à cinq compartiments.
Le premier indique le nom de la classe, le deuxième ses attributs et le troisième ses opérations. Un
compartiment des responsabilités peut être ajouté pour énumérer l'ensemble de tâches devant être
assurées par la classe, mais pour lesquelles on ne dispose pas encore assez d'informations. Un
compartiment des exceptions peut également être ajouté pour énumérer les situations
exceptionnelles devant être gérées par la classe.
Le nom de la classe doit évoquer le concept décrit par la classe. Il commence par une majuscule. On
peut ajouter des informations subsidiaires comme le nom de l'auteur de la modélisation, la date, etc.
Pour indiquer qu'une classe est abstraite, il faut ajouter le mot-clef abstract.
On peut ajouter aux méthodes définies sur les classes un ensemble de contraintes (types ou
propriété). Le type du paramètre peut être un nom de classe, un nom d'interface ou un type de
donnée prédéfini. Les propriétés correspondent à des contraintes ou à des informations
complémentaires comme les exceptions, les préconditions, les postconditions ou encore l'indication
qu'une méthode est abstraite (mot-clef abstract), etc.
Notons qu’un principe de conception important dans la modélisation objet consiste à protéger le
cœur d’un système des accès intempestifs venant de l’extérieur. C’est le principe de coffre-
fort appelé principe d’encapsulation en modélisation objet : seuls les détenteurs d’une clé peuvent
l’ouvrir. UML définit quatre niveaux d’encapsulation d’une propriété d’une classe :
Les attributs dérivés peuvent être calculés à partir d'autres attributs et de formules de calcul. Lors de
la conception, un attribut dérivé peut être utilisé comme marqueur jusqu'à ce que vous puissiez
déterminer les règles à lui appliquer.
Les attributs dérivés sont symbolisés par l'ajout d'un « / » devant leur nom.
Figure 4.2. Attribut dérivé d’une classe (Coan et al 2015).
Les classes sont les éléments de base d’un diagramme de classes. Une application nécessite sans
doute la modélisation de plusieurs classes. Après avoir identifié les classes dont on a besoin, il
convient de les relier entre elles. Les relations entre classes expriment le lien sémantique ou
structurel. Les relations les plus utilisées sont l’association, l’agrégation, la composition, la
dépendance et l’héritage.
4.3.1 La multiplicité
La multiplicité est définie par un ensemble non vide d’entiers positifs à l’exclusion d’un ensemble ne
contenant que zéro {0}. Elle apparaît à chaque extrémité d’une relation et indique le nombre d’objets
de la classe apparaissant à cette extrémité pouvant s’associer à un seul et unique objet de la classe
apparaissant dans l’autre extrémité.
Exemple : Un objet de la classe Voiture est composé d’au moins trois roues et d’au plus dix roues. Et
chaque roue se compose d’un seul pneu et d’une seule jante.
3..10
Dans la première version (figure 4.4), l'association apparaît clairement et constitue une entité
distincte. Dans la seconde, l'association se manifeste par la présence de deux attributs dans chacune
des classes en relation. C'est en fait la manière dont une association est généralement implémentée
dans un langage objet quelconque, mais pas dans tout langage de représentation.
La question de savoir s'il faut modéliser les associations en tant que telles a longtemps fait débat.
UML a tranché pour la première version, car elle se situe plus à un niveau conceptuel (par opposition
au niveau d'implémentation) et simplifie grandement la modélisation d'associations complexes
(comme les associations plusieurs à plusieurs par exemple).
Une association binaire est matérialisée par un trait plein entre les classes associées. Elle peut être
ornée d'un nom, avec éventuellement une précision du sens de lecture. Quand les deux extrémités
de l'association pointent vers la même classe, l'association est dite réflexive (Solnon 2015 ).
Une personne travail pour une et une seule entreprise. L’entreprise emploie au moins une personne.
L’entreprise est l’employeur des personnes qui travaillent pour elle et une personne a un statut
d’employé dans l’entreprise.
Figure 4.6. Association n-aire.
Une association n-aire lie plus de deux classes. Dans une association n-aire, la multiplicité
apparaissant sur le lien de chaque classe s'applique sur une instance de chacune des classes, à
l'exclusion de la classe-association et de la classe considérée. En effet, une multiplicité minimale de 1
(ou plus) sur une extrémité implique qu'il doit exister un lien (ou plus) pour TOUTES les combinaisons
possibles des instances des classes situées aux autres extrémités de l'association n-aire. On
représente une association n-aire par un grand losange avec un chemin partant vers chaque classe
participante. Le nom de l'association, le cas échéant, apparaît à proximité du losange.
Une association entre deux classes indique que les propriétés sont échangées ou partagées par les
classes reliées. L’ajout de contraintes à une association ou bien entre associations apporte plus
d’information car cela permet de mieux préciser la portée et le sens de l’association. La navigabilité
indique s'il est possible de traverser une association. On représente graphiquement la navigabilité
par une flèche du côté de l’extrémité navigable et on empêche la navigabilité par une croix du côté
de l’extrémité non navigable. Par défaut, une association est navigable dans les deux sens.
Par exemple, sur la figure ci-dessous, l’extrémité du côté de la classe Commande n'est pas navigable :
cela signifie que les instances de la classe Produit ne stockent pas de liste d'objets du
type Commande. Inversement, l’extrémité du côté de la classe Produit est navigable : chaque objet
commande contient une liste de produits.
Dans la figure ci-dessus, un polygone est défini par un ensemble de points jouant le rôle de sommets.
Les sommets du polygone ne sont accessibles que par la classe et par ses descendants. La navigabilité
est possible uniquement du polygone vers les points.
L’ajout de l’attribut sommets dans la classe Polygone permet de modéliser l’association entre les
classes Polygone et Point et mettre en évidence la navigabilité de la relation.
Une association dérivée est une association qui peut se déduire d’une asscociation existante ; elle est
donc conditionnée ou peut être déduite à partir d’une autre association. Graphiquement, une
association dérivée est symbolisée par l’ajout d’un slash avant le nom de l’association. Dans la figure
ci-dessous, l’asssociation dérivée /emploie indique que la personne qui travail dans une entreprise
est la même que celle associée à l’une des ses services.
Parfois, une association doit posséder des propriétés qui ne sont disponible dans aucune des classes
qu’elle lie. Comme, dans le modèle objet, seules les classes peuvent avoir des propriétés, cette
association devient alors une classe appelée « Classe-Association ».
Par exemple, l'association Emploie entre une société et une personne possède comme propriétés le
salaire et la date d'embauche. En effet, ces deux propriétés n'appartiennent ni à la société, qui peut
employer plusieurs personnes, ni aux personnes, qui peuvent avoir plusieurs emplois. Il s'agit donc
bien de propriétés de l'association Emploie. Les associations ne pouvant posséder de propriété, il
faut introduire un nouveau concept pour modéliser cette situation : celui de classe-association.
Une classe-association possède les caractéristiques des associations et des classes : elle se connecte
à deux ou plusieurs classes et possède également des attributs et des opérations.
Une classe-association est caractérisée par un trait discontinu entre la classe et l'association qu'elle
représente.
Notons qu’il n'est pas possible de rattacher une classe-association à plus d'une association puisque la
classe-association constitue elle-même l'association. Dans le cas où plusieurs classe-associations
doivent disposer des mêmes caractéristiques, elles doivent hériter d'une même classe possédant ces
caractéristiques, ou l'utiliser en tant qu'attribut.
Qualification d’une association pour limiter son impacte sur les classes associées
Généralement, une classe peut être décomposée en sous-classes ou posséder plusieurs propriétés.
Une telle classe rassemble un ensemble d'éléments (d'objets). Quand une classe est liée à une autre
classe par une association, il est parfois préférable de restreindre la portée de l'association à
quelques éléments ciblés (comme un ou plusieurs attributs) de la classe. Ces éléments ciblés sont
appelés un qualificatif. Un qualificatif permet donc de sélectionner un ou des objets dans le jeu des
objets d'un objet (appelé objet qualifié) relié par une association à un autre objet. L'objet sélectionné
par la valeur du qualificatif est appelé objet cible. L'association est appelée association qualifiée. Un
qualificatif agit toujours sur une association dont la multiplicité est plusieurs (avant que l'association
ne soit qualifiée) du côté cible.
Un objet qualifié et une valeur de qualificatif génèrent un objet cible lié unique. En considérant un
objet qualifié, chaque valeur de qualificatif désigne un objet cible unique.
L’objectif dans la figure ci-dessous est de modéliser l’association entre une personne et une banque.
L’unique lien entre les deux est le fait de posséder au plus 2 comptes. La banque assure bien d’autres
activités qui ne concernent pas le client. Pour mettre en évidence le fait que le lien entre la banque
et une personne se limite à la possession de plusieurs compte, on ajoute une classe Compte qui
représente la classe Banque dans l’association avec la classe Personne.
0..2 Posséder *
Banque #Compte Personne
e Client
Figure 4.11. Une classe qualifiante est collée à la classe principale (Charroux et al 2005).
Après avoir présenté la structure du diagramme de classes et son formalisme en détaillant ses
relations structurelles (Associations), nous allons présenter dans cette section les autres types de
relation qui sont très utiles dans la modélisation objet.
Une agrégation est une forme particulière d’association. Elle représente la relation d’inclusion
structurelle ou comportementale d’un élément dans un ensemble. Contrairement à l’association,
l’agrégation est une relation transitive. Graphiquement, l’agrégation se distingue d’une association
par l’ajout d’un losange vide du côté de l’agrégat.
La composition est une agrégation particulière. Cela signifie que toute composition peut être
remplacée par une agrégation mais avec perte d’information. La relation de composition décrit une
contenance structurelle entre instances. Ceci implique que l’élément composite est responsable de la
création de la copie et de la destruction de ses composants. Dans la figure ci-dessous la tête est le
tronc sont des composites d’un homme. Un homme peut très bien perdre une jambe ou un bras et
donc la relation entre bras et jambe est une agrégation.
Une dépendance est une relation unidirectionnelle exprimant une dépendance sémantique entre des
éléments du modèle. Elle est représentée par un trait discontinu orienté. Elle indique que la
modification de la cible peut impliquer une modification de la source. La dépendance est souvent
stéréotypée pour mieux expliciter le lien sémantique entre les éléments du modèle.
On utilise souvent une dépendance quand une classe en utilise une autre comme argument dans la
signature d'une opération. Par exemple, le diagramme de la figure ci-dessous montre que la
classe Confrontation utilise la classe Stratégie, car la classe Confrontation possède une
méthode confronter dont deux paramètres sont du type Stratégie. Si la classe Stratégie, notamment
son interface, change, alors des modifications devront également être apportées à la
classe Confrontation.
La généralisation décrit une relation entre une classe générale (classe de base ou classe parent) et
une classe spécialisée (sous-classe). La classe spécialisée est intégralement cohérente avec la classe
de base, mais comporte des informations supplémentaires (attributs, opérations, associations). Un
objet de la classe spécialisée peut être utilisé partout où un objet de la classe de base est autorisé.
Dans le langage UML, ainsi que dans la plupart des langages objet, cette relation de généralisation se
traduit par le concept d'héritage. On parle également de relation d'héritage. Ainsi, l'héritage permet
la classification des objets.
Le symbole utilisé pour la relation d'héritage ou de généralisation est une flèche avec un trait plein
dont la pointe est un triangle fermé désignant le cas le plus général.
la classe enfant possède toutes les caractéristiques de ses classes parents, mais elle ne peut
accéder aux caractéristiques privées de cette dernière ;
une classe enfant peut redéfinir (même signature) une ou plusieurs méthodes de la classe
parent. Sauf indication contraire, un objet utilise les opérations les plus spécialisées dans la
hiérarchie des classes ;
toutes les associations de la classe parent s'appliquent aux classes dérivées ;
l’héritage multiple concerne le fait qu’une classe fille peut avoir plus d’une classe mère.
Figure 4.13. Relation d’héritage.
4.5 Conclusion
Nous avons commencé, dans ce chapitre par la définition de la notion de classe qui adopte un niveau
élevé d’abstraction afin de modéliser d’une façon concise un ensemble d’objets. Nous avons
présenté dans le formalisme de diagramme de classes la notion d’association afin de faciliter la
compréhension de la modélisation d’un diagramme de classes en utilisant uniquement des
associations. Nous avons ensuite présenté les autres types de relations et leurs différences qui
permettent de modéliser la diversité des cas rencontrés lors de la modélisation objet.
5.1 Introduction
L’objet entrep, modélise lui une entreprise particulière (PERTNE) qui emploie trois personnes. La
relation de dépendance d'instanciation (stéréotypée << instanceof >>) décrit la relation entre un
classeur et ses instances. Elle relie, en particulier, les liens aux associations et les objets aux
classes. Dans un diagramme d’objets, les relations du diagramme de classes deviennent des liens. La
relation de généralisation ne possède pas d'instance, elle n'est donc jamais représentée dans un
diagramme d’objets. Graphiquement, un lien se représente comme une relation, mais, s'il y a un
nom, il est souligné. Naturellement, on ne représente pas les multiplicités.
Par exemple, le diagramme de classes de la figure 5.1 montre qu'une entreprise emploie au moins
deux personnes et qu'une personne travaille dans au plus deux entreprises. Le diagramme d’objets
Figure 5.2. Dépendance d'instanciation entre les classeurs et leurs instances (Charroux et al 2005).
Un diagramme d’objets est particulièrement utile pour décrire comment les objets dans le
système fonctionnent ensemble dans un scénario donné. Un diagramme d’objets représente une
configuration donnée. Clairement, un diagramme d’objets doit respecter les contraintes d’un
diagramme de classes : par exemple, ne pas tracer de liens entre deux objets dont les classes ne sont
pas reliées dans le diagramme de classes.
Les objets ne sont pas des éléments statiques et leur durée de vie ne correspond pas forcément à la
durée d'exécution du programme.
Un objet composite est constitué d'un ou de plusieurs objets similaires (ayant des fonctionnalités
similaires). L'idée est de manipuler un groupe d’objets de la même façon que s'il s'agissait d'un seul
objet. Les objets ainsi regroupés doivent posséder des opérations communes, c'est-à-dire un
"dénominateur commun". Dans l’exemple ci-dessous un livre est constitué d’un N chapitres il est
donc composite, la relation entre classes est une composition. Un objet livre est un objet composite.
Une contrainte constitue une condition ou une restriction sémantique exprimée sous forme
d'instruction dans un langage textuel qui peut être naturel ou formel. En général, une contrainte
peut être attachée à n'importe quel élément de modèle ou liste d'éléments de modèle. Une
contrainte désigne une restriction qui doit être appliquée par une implémentation correcte du
système.
On représente une contrainte sous la forme d'une chaîne de texte placée entre accolades ({}). La
chaîne constitue le corps écrit dans un langage de contrainte qui peut être :
naturel ;
dédié, comme OCL ;
ou encore directement issu d'un langage de programmation.
Si une contrainte possède un nom, on présente celui-ci sous forme d'une chaîne suivie d'un double
point (:), le tout précédant le texte de la contrainte.
La figure 5.4 présente quelques contraintes prédéfinies ({frozen}, {ordered} et {addonly}). Frozen
précise que le nombre de payés dans lequel la personne est née ne peut pas varier ici nombre=1.
Une personne ne peut naitre que dans un seul payé. Le addonly signifie que le payé est une instance
que l’on peut ajouter mais on ne peut le retirer. Ordered signifie que les valeurs sont ordonnées.
UML permet d'associer une contrainte à un, ou plusieurs, élément(s) (Audibert 2009) de modèle de
différentes façons :
Le diagramme de la figure 5.4 introduit des nouvelles contraintes et montre comment les utiliser. La
liste est encore longue, mais le pouvoir expressif de ces contraintes reste insuffisant et l’utilisation
d’un langage de contraintes devient une véritable nécessité. Le langage de contraintes objet OCL
apporte une solution élégante à cette insuffisance.
5.3.5 Le langage de contrainte OCL
C'est avec OCL (Object Constraint Language) qu'UML formalise l'expression des contraintes. Il s'agit
donc d'un langage formel d'expression de contraintes bien adapté aux diagrammes d'UML, et en
particulier au diagramme de classes.
OCL existe depuis la version 1.1 d'UML et est une contribution d'IBM. OCL fait partie intégrante de la
norme UML depuis la version 1.3 d'UML. Dans le cadre d'UML 2.0, les spécifications du langage OCL
figurent dans un document indépendant de la norme d'UML, décrivant en détail la syntaxe formelle
et la façon d'utiliser ce langage.
Figure 5.5. Diagramme d’objets valide mais ne respectant parfaitement les spécifications.
La figure ci-dessus présente un diagramme d’objets valide vis-à-vis du diagramme de classes mais ne
respecte pas la spécification attendue :
- Une personne a un compte dans une banque où elle n'est pas cliente
- Une personne est cliente d'une banque mais sans y avoir de compte
OCL peut s'appliquer sur la plupart des diagrammes d'UML (Barbier et al 2005) et permet de
spécifier des contraintes sur l'état d'un objet ou d'un ensemble d’objets comme :
context Compte
inv: proprié[Link] >= 18// Le propriétaire d'un compte doit avoir plus de 18 ans
inv: solde > 0 // Pour toutes les instances de la classe Compte, l'attribut solde doit toujours être positif
context Compte : débiter(somme : int)
pre: somme > 0 //précondition solde >0
post: solde = solde@pre – somme // Postcondition : la somme à débiter doit être positive pour que l'appel
de l'opération soit valide. Après l'exécution de l'opération, l'attribut solde doit avoir pour valeur la différence de
sa valeur avant l'appel et de la somme passée en paramètre
context Compte
inv: [Link] -> includes (propriétaire) // une personne ne peut avoir un compte dans une banque où
elle n'est pas cliente et une personne est cliente d'une banque mais sans y avoir de compte
Nous allons montrer comment implémenter une classe simple ainsi que l’instanciation de ces objets
dans la classe main. Notons qu’on s’est basé sur les exemples d’implémentations présentés dans le
livre de UML2 de l’apprentissage à la pratique de Laurent Audibert (Audibert 2009) .
public class A {
public String a1;
package String a2;
protected String a3;
private String a4;
public void op1() {
...
}
public void op2() {
...
}
}
Instanciation de l’objet dans la fonction main
…
public static void main(String[] args){
A a = new A(); // instanciation de la
classe A et l’objet instanciée
exécutera automatiquement le
constructeur.
}
…
public class A {
private B rb;
public void addB( B b ) {
if( b != null ){
if ( [Link]() != null ) { // si b est déjà connecté à un
autre A
[Link]().setB(null); // cet autre A doit se déconnecter
}
[Link]( b );
[Link]( this );
}
}
public B getB() { return( rb ); }
public void setB( B b ) { [Link]=b; }
}
public class B {
private A ra;
public void addA( A a ) {
if( a != null ) {
if ([Link]() != null) { // si a est déjà connecté à un
autre B
[Link]().setA( null ); // cet autre B doit se déconnecter
}
[Link]( a );
[Link]( this );
}
}
public void setA(A a){ [Link]=a; }
public A getA(){ return(ra); }
}
5.4.2 Implémentation de la relation bidirectionnelle 1-N
public class A {
private ArrayList <B> rb;
public A() { rb = new ArrayList<B>(); }
public ArrayList <B> getArray() {return(rb);}
public void remove(B b){[Link](b);}
public void addB(B b){
if(  ){
if ([Link]()!=null) [Link]().remove(b);
[Link](this);
[Link](b);
}
}
}
public class B {
private A ra;
public B() {}
public A getA() { return (ra); }
public void setA(A a){ [Link]=a; }
public void addA(A a){
if( a != null ) {
if( ![Link]().contains(this)) {
if (ra != null) [Link](this);
[Link](a);
[Link]().add(this);
}
}
}
}
public class A {
private ArrayList <B> rb;
public A() { rb = new ArrayList<B>(); }
public void addB(B b){
if(  ) {
[Link](b);
}
}
}
public class B {
... // B ne connaît pas l'existence de A
}
5.4.4 Implémentation de la relation unidirectionnelle 1-1
public class A {
private B rb;
public void addB( B b ) {
if( b != null ) {
[Link]=b;
}
}
}
public class B {
... // La classe B ne connaît pas l'existence de la
classe A
}
5.5 Conclusion
Nous avons présenté dans ce chapitre le diagramme d’objets qui représente une ou plusieurs
instanciations du diagramme de classes pour faciliter la validation de celui-ci. Nous avons vu qu’un
diagramme d’objets représente un état du système en utilisant l’ensemble des contraintes
prédéfinies. Ces contraintes doivent être formulées en utilisant le langage OCL. Nous avons montré
que l’utilisation d’OCL permet d’organiser le travail.
Ce chapitre a montré comment implémenter le diagramme de classes afin de s’orienter sur le point
de vue implémentation. L’objectif était de présenter des exemples de contenu d’implémentation
facilitant la compréhension du diagramme d’objets et son utilisation dans le système. Un diagramme
d’objets donc ne montre pas l'évolution du système dans le temps. Pour représenter ce fait, en se
basant sur les interactions au fil du temps, il faut utiliser le diagramme d’interaction. Le chapitre
suivant présentera le diagramme d’interaction.