Génie logiciel
UML : Unified Modeling Language
A. Madani (madaniabdellah@[Link])
1
Génie Logiciel
UML – Partie II
Rappels (partie I)
Passage vers le code
De UML vers Java
UML et les bases de données
Langage de contraintes : OCL
Études de cas
De l’analyse des besoins au code
Designs patterns
Introduction
Patterns de création
Patterns structuraux
Patterns comportementaux
2
Diagramme d’UML (Rappels)
Cas d’utilisation
Objets Composants
Classes Vue logique statique Vue Implémentation
(Structure des objets) (composants logiciels)
Vue externe
(fonctions système)
Séquence Vue déploiement
Vue logique dynamique
(Environnement
(Comportement)
d’implantation)
Collaboration
Activités
États transitions Déploiement
3
Correspondance UML et Java
madaniabdellah@[Link]
4
Traduction d’une classe
La classe est le concept fondamental de
toute technologie objet.
Le mot-clé correspondant existe bien sûr
également en Java.
De plus, chaque classe UML devient par
défaut un fichier .java.
5
Traduction d’une classe
class Personne{
…
…
Personne ….
}
6
Traduction d’une classe
Une classe abstraite est simplement une
classe qui ne s’instancie pas directement
mais qui représente une pure abstraction afin
de factoriser des propriétés.
Elle se note avec {abstract} en UML et se
traduit par le mot-clé abstract en Java.
7
Traduction d’une classe
abstract class Personne{
….
….
Personne ….
{abstract} }
8
Traduction d’une classe
Une interface est une classe spéciale dont
toutes les méthodes sont abstraites
Une interface se note en UML avec le
symbole
En java, elle traduite par le mot clé ‘interface’
9
Traduction d’une classe
interface Forme {
…
…
Forme …
}
10
Traduction des attributs
Les attributs UML deviennent simplement
des attributs en Java
Leur type est soit un type primitif (int, etc.),
soit une classe.
La visibilité des attributs est montrée
graphiquement en UML en les faisant
précéder par + pour public, # pour protégé
(protected), - pour privé (private).
Les attributs de classe en UML deviennent
des membres statiques en Java (static).
11
Traduction des opérations
Les opérations UML deviennent très
directement des méthodes en Java.
Leur visibilité est définie graphiquement avec
les mêmes conventions que les attributs.
Les opérations de classe deviennent des
méthodes statiques (static).
Les opérations abstraites (en italiques) se
traduisent par le mot-clé abstract en Java.
12
Traduction des opérations
class Personne {
private int code;
private String nom;
private static int nombre;
public Personne() {
}
public static int getNombre(){
}
public String getInf(){
}
}
13
Traduction des relations
Les relations UML entre concepts statiques
sont très riches. On peut distinguer les
relations de :
Généralisation (héritage)
Réalisation
Association, avec ses variantes : agrégation
et composition.
14
Traduction des relations
(La généralisation)
Le concept UML de généralisation se traduit
directement par le mécanisme de l’héritage
dans les langages objets.
Java, contrairement à C++ interdit l’héritage
multiple entre classes.
15
Traduction des relations
(La généralisation)
Class Personne{
Personne …
…
…
}
Class Employe extends
Employe Personne{
…
…
…
}
16
Traduction des relations
(La réalisation )
Une classe UML peut implémenter plusieurs
interfaces.
Contrairement à C++, le langage Java
propose directement ce mécanisme.
17
Traduction des relations
(Réalisation)
interface A{
…
A B …
}
interface B{
…
…
}
C class C implements A, B {
…
…
}
18
Traduction des relations
(Les associations)
Les associations navigables UML se
traduisent par du code Java qui dépend de :
la multiplicité de l’extrémité concernée (pointée
par la flèche)
mais aussi de l’existence ou pas d’une contrainte
{ordered} ou d’un qualificatif.
Nous allons voir tout cela du plus simple au
plus complexe :
Une association navigable avec une multiplicité 1
Une association navigable avec une multiplicité *
19
Traduction des relations
(Les associations)
Une association navigable avec une
multiplicité 1 se traduit par une variable
d’instance de type référence vers une
instance de classe.
Une multiplicité « * » va se traduire par un
attribut de type collection de références
d’objets au lieu d’une simple référence sur un
objet.
20
Traduction des relations
(Les associations)
La difficulté consiste à choisir la bonne collection
parmi les très nombreuses classes de base que
propose Java.
Bien qu’il soit possible de créer des tableaux
d’objets, ce n’est pas forcément la bonne solution.
En pratique, on préfère plutôt recourir à des
collections, parmi lesquelles les plus utilisées sont :
ArrayList, SortedList et HashTable.
Utilisez ArrayList si vous devez respecter un ordre et
récupérer les objets à partir d’un indice entier
Utilisez HashTable si vous souhaitez récupérer les objets à
partir d’une clé arbitraire.
21
Traduction des relations
(Les associations)
22
Traduction des relations
(Les associations)
Une association bidirectionnelle se traduit
simplement par une paire de références, une
dans chaque classe impliquée dans
l’association.
Les noms des rôles aux extrémités d’une
association servent à nommer les variables
de type référence.
23
Traduction des relations
(Les associations)
24
Traduction des relations
(Les associations)
25
Traduction des relations
(La classe association)
Elle possède tout à la fois les caractéristiques
d’une association et d’une classe et peut
donc porter des attributs qui se valorisent
pour chaque lien.
Ce concept UML avancé n’existe pas dans
les langages de programmation objet, il faut
donc le traduire en le transformant en classe
normale, et en ajoutant des variables de type
référence.
26
Traduction des relations
(La classe association)
27
UML
De UML vers le modèle relationnel
abdellah_madani@[Link] 28
De UML vers le modèle relationnel
Cette partie traite le passage de la
conception faite par UML vers le modèle
relationnel
La traduction concerne
Classes, instances, attributs
Relations entres classes :
Associations,
Agrégation,
Composition,
Généralisation spécialisation
abdellah_madani@[Link] 29
Classe en Relationnel
Dans le cas général une classe est traduite
par une table
Chaque objet est conservé dans une ligne de
la table
Un champ jouant le rôle de clé primaire est
ajouté même s'il n'existait pas dans la classe
abdellah_madani@[Link] 30
Traduction d'une classe
En Relationnel
Compte(NCompte, Solde)
Compte
En SQL
- N°Compte : int
Create table Compte( - Solde : float
+ <<Constructor>> Compte (int N°Compte, float Solde)
NCompte smallint, + deposer (float Solde) : void
+ retirer (float Solde) : float
Solde decimal, + avoirSolde () : String
Primary key PK_Compte (NCompte)
)
abdellah_madani@[Link] 31
Généralisation/spécialisation en
Relationnel
Plusieurs méthodes de traduction en
Relationnel :
Représenter toutes les classes d’une
arborescence d’héritage par une seule table
relationnelle
Représenter chaque classe par une table
abdellah_madani@[Link] 32
Généralisation/spécialisation en
Relationnel
La solution la plus simple est de modéliser
toute une hiérarchie de classes dans une
même table
Chaque classe ajoutant ses propres attributs
comme de nouveaux champs.
Il nous suffit alors d’ajouter un champ
contenant le type de l’instance pour pouvoir
charger les champs correspondants.
abdellah_madani@[Link] 33
Généralisation/spécialisation en
Relationnel
abdellah_madani@[Link] 34
Associations en Relationnel
(Association un-à-un)
Deux solutions sont possibles :
une clé étrangère dans chacune des tables
associées
la fusion des deux tables dans une seule
abdellah_madani@[Link] 35
Associations en Relationnel
(Association un-à-un)
1ère Solution
Pays(IdPays, NomP,#IdCapitale)
Capitales(IdCapitale, NomC, #IdPays)
2ième Solution
Pays(IdPays, NomP, NomC)
abdellah_madani@[Link] 36
Associations en Relationnel
(Association un-à-un)
1ère Solution
create table Pays(IdPays integer primary key,
…
IdCapitale integer foreign key references capitales
(IdCapitale))
et
create table Capitales(IdCapitale integer primary key,
…,
IdPays integer foreign key refernces pays(IdPays))
2ième Solution
Pays(IdPays integer primary key,
NomP varchar(20),
NomC varchar(20))
abdellah_madani@[Link] 37
Associations en Relationnel
(Association un-à-plusieurs)
Une seule solution est possible :
migration de la clé du côté de 1 vers la table
du côté de plusieurs
La clé migrée jouera le rôle de clé étrangère
abdellah_madani@[Link] 38
Associations en Relationnel
(Association un-à-plusieurs)
En Relationnel
Dept(IdDept, Nomdept)
Emp(IdEmp, NomEmp, #IdDept)
En SQL
Create table dept(…)
Create table emp(IdEmp integer primary key,
NomEmp varchar(20),
IdDept integer foreign key references Dept(IdDept)
)
abdellah_madani@[Link] 39
Associations en Relationnel
(Association plusieurs-à-plusieurs)
L’association est traduite par une table dont
la clé primaire est la concaténation des clés
primaires des tables associées
La table résultante aura :
Une seule clé primaire
Deux clés étrangères
abdellah_madani@[Link] 40
Traduction des associations en Relationnel
(Association plusieurs-à-plusieurs)
En Relationnel
Articles(Ref, Des, PU)
Commandes(NBC, DateC, Client)
Détails(#NBC, #Ref, Qté)
abdellah_madani@[Link] 41
Traduction des associations en Relationnel
(Association plusieurs-à-plusieurs)
En SQL
1. create table Article(Ref integer primary key, …)
2. create table Cde(NBC integer primary key, …)
3. create table Detail(NBC integer, Ref integer,…,
constraint PK primary key(NBC, Ref),
constraint FK1 foreign key(NBC) references cdes(NBC),
Constraint FK1 foreign key(NBC) references cdes(NBC))
abdellah_madani@[Link] 42
OCL
43
Contraintes
Une contrainte est une condition ou une
restriction sémantique exprimée sous forme
d’instructions dans un langage textuel qui
peut être naturel ou formel
Elle doit être appliquée lors de
l’implémentation
Représentée sous forme d’une chaîne placée
entre accolades({})
44
Contraintes
Nous avons vu comment exprimer certaines
contraintes avec UML
{ordered}
{subset}
{frozen}
{xor}
…
45
Contraintes – Exemple -
Dans cet exemple, on exprime le fait qu’un
‘solde’ doit rester toujours positif (utilisation
d’un langage formel).
46
Contraintes – Exemple -
Dans cet exemple, on exprime un contrainte
avec un langage textuel non formel
47
Introduction
OCL est un langage de contraintes associé à
UML
Il peut être utilisé pour contraindre n’importe
quel diagramme
48
Contexte
Une contrainte est toujours associée à un élément
du modèle
Cet élément constitue le contexte de la contrainte
Deux manières pour exprimer le contexte d’une
contrainte :
En écrivant la contrainte entre {} dans une note (voir
exemple précédent)
En utilisant le mot clé ‘context’ dans un document
accompagnant le modèle
49
Contexte
Syntaxe
context <élément>
Où : <élément> : peut être une classe, un attribut,
une opération, etc.
Pour faire référence à un élément d’une
classe, il faut utiliser les ‘::’
50
Contexte
Le contexte de la classe ‘Compte’
context Compte
Le contexte de l’opération getSolde() de la
classe Compte
context Compte::getSolde():Real
Le contexte de l’opération deposer() de la
classe Compte
context Compte::deposer(somme:Real)
51
Invariants
Un invariant exprime une contraintes sur un
objet ou un groupe d’objets qui doit être
respectée en permanence
Syntaxe :
inv : <expression_logique>
L’expression logique doit être toujours vraie
52
Invariants
Exemple :
Le solde d’un compte doit être toujours positif
context Compte
inv : solde>0
53
Préconditions et postconditions
Une précondition permet de spécifier une
condition qui doit être vérifiée avant l’appel
d’une opération.
Une postcondition permet de spécifier une
condition qui doit être vérifiée après l’appel
d’une opération.
54
Préconditions et postconditions
Dans l’expression de la contrainte de la
postcondition, deux éléments particuliers sont
utilisés :
result : la valeur retournée par l’opération
<attribut>@pre : la valeur de l’attribut avant
l’appel de l’opération
55
Préconditions et postconditions
Syntaxe de la précondition
pre : <expression logique>
Syntaxe de la postcondition
post : <expression logique>
56
Préconditions et postconditions
Exemples :
context Compte::debiter(somme : Real)
pre : somme>0
post : solde=solde@pre-somme
context Compte::getSolde():Real
post : result=solde
57
Résultat d’une opération
L’expression de contrainte ‘body’ permet
définir directement le résultat d’une
opération
Syntaxe :
body : <requête>
<requête> : expression qui retourne le résultat
dont le type est compatible avec le type de
retour de l’opération
58
Résultat d’une opération
Exemple
La méthode getSolde() de la classe ‘Compte’
retourne le solde actuel
context Compte::getSolde():Real
body : solde
59
Définition des attributs et de méthodes
Motivation :
une sous expression peut être utilisée plusieurs fois dans
une expression
Deux expressions de contraintes :
let : permet de déclarer et d’initialiser un attribut qui peut
être utilisé dans l’expression qui suit le mot clé in
def : fait la même chose que let.
60
Définition des attributs et de méthodes
Syntaxes :
let <déclaration>=<requête> in <expression>
L’attribut déclaré recevra le résultat de la
<requête> dans toute l’<expression>
def : <déclaration>=<requête>
61
Définition des attributs et de méthodes
Exemples
1. context Personne
inv : let argent=[Link]->sum() in
age>=18 implies argent>0
2. context Personne
def : argent : Real = [Link]-
>sum()
3. context Personne
inv : age>=18 implies argent>0
62
Initialisation et évolution des attributs
Le type de contrainte init permet de préciser
la valeur initiale d’un attribut ou d’une
terminaison d’association
La valeur d’un attribut dérivé est définie par la
contrainte derive.
Syntaxes :
init : <requête>
derive : <requête>
63
Initialisation et évolution des attributs
Exemple
Quand on crée une personne, la valeur initiale
de l’attribut marié est faux, et la personne ne
possède pas d’employeur.
context Personne::marié:Boolean
init : false
context Personne::employeur:Set(Société)
init : set{}
64
Initialisation et évolution des attributs
Exemple
L’âge d’une personne est la différence entre la
date courante et la date de naissance de la
personne.
context Personne::age:Integer
derive : Date::current() – date_de_naissance
65
Types et opération OCL
Le langage OCL possède un certain nombre de
types prédéfinis et d’opérations prédéfinies
sur ces types :
Boolean
Integer
Real
String
66
Types et opération OCL
Type opérateurs
Boolean And, or, xor, not, implies, if…then…else…endif
Integer +,-, *, /, abs(), …
Real +,-, *, /, abs(), floor(), …
String Concat(), size(), substring(), …
67
Types et opération OCL
a b a and b a or b a xor b a implies b
V V V V F V
V F F V V F
F V F V V V
F F F F F V
68
Types et opération OCL
not If <exp_log0>
Then <exp_log1>
V F
Else <exp_log2>
Endif
F V
69
Collections
Le langage OCL manipule plusieurs
collections :
Set : collection non ordonnée d’éléments uniques
orderedSet : collection ordonnée d’éléments
uniques
Bag : collection non ordonnée d’éléments
Sequence : collection ordonnée d’éléments
70
Collections
Collection Éléments ordonnées Éléments uniques
Set Non Oui
OrderedSet Oui Oui
Bag Non Non
Sequence Oui Non
71
Quelques opérations sur les collections
- Opération de base -
La syntaxe : collection->operation()
size() : nombre d’éléments
count() : nombre d’occurrences
sum() : somme des éléments
isEmpty() : est vide
notEmpty() : non vide
includes(el) : appartenance
excludes(el) : non appartenance
includesAll(col) : inclusion
excludesAll(col) : exclusion
72
Quelques opérations sur les collections
- Filtrage -
select(cond) : retient les éléments qui vérifient la condition
reject(cond) : élimine les éléments qui vérifient la condition
any(cond) : retourne l’un des éléments qui vérifie la
condition
forAll(cond) : true si tous les éléments vérifient la
condition
exists(cond) : true si au moins un élément vérifie la
condition
isUnique(exp) : true si une et une seule valeur de la
collection qui vérifie la condition
73
Opération ensembliste
- Set ou OrederedSet -
union(ens) : union
- : différence (ens1 – ens2)
including(el) : ajoute un élément
excluding(el) : retire un élément
74
Accès aux données de l’objet courant
Pour faire référence à une donnée (attribut
ou opération) d’un objet désigné par le
contexte :
1. Utiliser le nom de l’élément
2. Faire précéder le nom de l’élément du mot clé
‘self’
75
Accès aux données de l’objet courant
Exemple
Dans le contexte de la classe ‘Compte’ :
Context Compte
Inv : solde > 0
Context Compte::debiter(somme : Real)
Pre : somme > 0
Post : [Link] = [Link]@pre - somme
76
Navigation à travers une association
Pour faire référence à un objet (ou un groupe
d’objets) associé via une association, On
utilise :
Le nom de la classe associée en minuscule
Le nom du rôle côté de la classe associée
77
Navigation à travers une association
Dans le contexte de la classe ‘Personne’, on
fait référence à la classe société avec l’une
des deux méthodes :
employeur
société
De même pour accéder à l’adresse de la
société :
[Link]
société.adresse
78
Navigation à travers une association
Exemple
L’adresse de la société employant une
personne est constituée d’au moins 10
caractères
Context Personne
Inv: [Link]()>=10
Ou encore
Context Personne
Inv: société.[Link]()>=10
79
Navigation à travers une association
L’utilisation du rôle est indispensable si :
1. Il existe plusieurs associations entre l’objet
désigné par le contexte et l’objet auquel on
désire accéder
2. L’association est réflexive
80
Navigation à travers une association
Exemple
Dans le contexte de la classe Avion :
pilote->size()>0 and pilote->size()<5
passager->size()>40
Dans le contexte de la classe Personne
[Link]>=18
[Link]>=20
81
Navigation à travers une association
Le type du résultat dépend de :
la multiplicité de l’objet référencé
type de l’objet référence proprement dit.
Si l’objet référencé est T, alors le résultat est
de type :
T, si la multiplicité est 0..1 ou 1..1
Set(T), si la multiplicité est *
OrderedSet(T), si la multiplicité est * avec
{ordered}
82
Navigation à travers une association
Exemple : Type du résultat
83
Navigation à travers une association
qualifiée
Dans une association qualifiée, on utilise les
valeurs des qualificatifs entre crochets ([])
context Banque
inv : [Link][8900].solde>0
84
Navigation vers une classe association
Dans le contexte de Société, [Link]:
salaire de tous les employés
Dans le contexte de Personne,
[Link][epouse].date : dates de mariages
des femmes
85
Navigation depuis une classe association
context Poste
inv : [Link]>21
(ou aussi, [Link]>21)
86