03.08.2013 Views

Rapport de fin de phase I - Haute école du paysage, d'ingénierie et ...

Rapport de fin de phase I - Haute école du paysage, d'ingénierie et ...

Rapport de fin de phase I - Haute école du paysage, d'ingénierie et ...

SHOW MORE
SHOW LESS

You also want an ePaper? Increase the reach of your titles

YUMPU automatically turns print PDFs into web optimized ePapers that Google loves.

Cadre <strong>du</strong> proj<strong>et</strong><br />

ISN<strong>et</strong>35 <strong>Rapport</strong> <strong>phase</strong> I<br />

Ce proj<strong>et</strong> à été déposé dans le centre <strong>de</strong> compétence Informatique <strong>de</strong> gestion <strong>et</strong><br />

systèmes (ISN<strong>et</strong>) dans le cadre <strong>du</strong> programme <strong>de</strong> la réserve stratégique <strong>de</strong> la HES-SO en<br />

septembre 2001. Il est sous la responsabilité <strong>du</strong> Laboratoire <strong>de</strong> Technologie Obj<strong>et</strong> <strong>de</strong> la<br />

<strong>Haute</strong> Ecole <strong>de</strong> Gestion <strong>de</strong> Genève.<br />

1.1. Rappel <strong>de</strong>s objectifs <strong>du</strong> proj<strong>et</strong><br />

Les objectifs <strong>du</strong> proj<strong>et</strong> sont initialement dé<strong>fin</strong>is ainsi :<br />

A partir <strong>de</strong>s classes Java obtenues à l'issue d'un processus d'Analyse <strong>et</strong> <strong>de</strong> Conception<br />

• Concevoir un processus générique automatique d'implantation <strong>de</strong> la persistance<br />

d'obj<strong>et</strong>s Java dans une base <strong>de</strong> données relationnelle-obj<strong>et</strong>, offrant en particulier les<br />

possibilités<br />

<strong>de</strong> gérer c<strong>et</strong>te persistance <strong>de</strong> façon transparente pour le programme d'application<br />

Java,<br />

<strong>de</strong> perm<strong>et</strong>tre l'accès aux données représentées par les obj<strong>et</strong>s Java par <strong>de</strong>s<br />

applications quelconques en préservant l'intégrité <strong>de</strong>s données.<br />

• Elaborer une démarche méthodologique perm<strong>et</strong>tant <strong>de</strong> comparer le résultat <strong>de</strong> ce<br />

processus aux technologies existantes.<br />

• Réaliser <strong>et</strong> vali<strong>de</strong>r un prototype implantant effectivement ce processus générique.<br />

• Rédiger une publication qui sera soumise à une revue spécialisée.<br />

1.2. Document<br />

Le présent document est le rapport <strong>de</strong> synthèse <strong>du</strong> travail <strong>du</strong> groupe <strong>de</strong> compétence<br />

ISN<strong>et</strong>-Ne <strong>de</strong> la <strong>Haute</strong> <strong>école</strong> Neuchâteloise en <strong>fin</strong> <strong>de</strong> <strong>phase</strong> I <strong>du</strong> proj<strong>et</strong>, son contenu <strong>de</strong>vra<br />

s’intégrer dans le cadre global <strong>du</strong> proj<strong>et</strong>.<br />

L’activité <strong>de</strong> l’équipe neuchâteloise s’est principalement orientée sur la problématique <strong>de</strong><br />

la persistance <strong>de</strong>s obj<strong>et</strong>s <strong>et</strong> <strong>du</strong> langage <strong>de</strong> dé<strong>fin</strong>ition <strong>de</strong>s contraintes.<br />

1.3. Objectifs <strong>de</strong> la <strong>phase</strong> I<br />

La <strong>phase</strong> I, intitulée Conception <strong>du</strong> processus automatique <strong>et</strong> élaboration <strong>de</strong> la démarche<br />

méthodologique est dé<strong>fin</strong>ie par les objectifs suivant :<br />

• Etudier les entités <strong>et</strong> concepts susceptibles d'être mémorisés dans la base <strong>de</strong> données<br />

relationnelle-obj<strong>et</strong> (classes, héritage, attributs, relations entre classes, …) ;<br />

• Dé<strong>fin</strong>ir une représentation adéquate <strong>de</strong> ces entités <strong>et</strong> concepts dans la base <strong>de</strong><br />

données relationnelle-obj<strong>et</strong> ; <strong>de</strong>ux représentations seront envisagées :<br />

relationnelle-obj<strong>et</strong> pure,<br />

vue relationnelle-obj<strong>et</strong><br />

• Concevoir une dé<strong>fin</strong>ition <strong>de</strong>s contraintes d'intégrité auxquelles ces représentations<br />

<strong>de</strong>vront être soumises <strong>de</strong> telle sorte qu'elles n'invali<strong>de</strong>nt ni la représentation obj<strong>et</strong>, ni<br />

la représentation relationnelle-obj<strong>et</strong> <strong>de</strong>s informations gérées ;<br />

• Elaborer une démarche méthodologique perm<strong>et</strong>tant <strong>de</strong> comparer les diverses<br />

technologies réalisant la persistance (relationnelle pure, relationnelle-obj<strong>et</strong>, vue<br />

relationnelle-obj<strong>et</strong>) ;<br />

• Pro<strong>du</strong>ire un document <strong>de</strong> synthèse comprenant :<br />

22.06.2005 1/78


une <strong>de</strong>scription <strong>de</strong> la démarche méthodologique d'évaluation,<br />

un cahier <strong>de</strong>s charges <strong>du</strong> prototype qui sera réalisé dans la secon<strong>de</strong> <strong>phase</strong> <strong>du</strong><br />

proj<strong>et</strong>.<br />

Problématique<br />

1.4. Gestion <strong>de</strong> la persistance<br />

En informatique <strong>de</strong> gestion, les informations qui concernent le métier d’une entreprise sont<br />

toujours persistantes. Il est en eff<strong>et</strong> inimaginable que le comptable d’une entreprise ressaisisse<br />

dans son logiciel <strong>de</strong> comptabilité tous les matins les écritures <strong>de</strong> l’exercice courrant avant <strong>de</strong><br />

pouvoir imprimer le bilan <strong>de</strong> la pério<strong>de</strong>.<br />

De façon générale, un programme d’informatique <strong>de</strong> gestion fonctionne selon le principe<br />

suivant :<br />

Phase A<br />

1. L’utilisateur saisit <strong>de</strong>s informations dans un formulaire a<strong>fin</strong> <strong>de</strong> créer un nouvel<br />

enregistrement<br />

2. Le logiciel mémorise l’enregistrement dans sa base <strong>de</strong> données<br />

Phase B<br />

1. L’utilisateur remplit un formulaire <strong>de</strong> filtre<br />

2. Le logiciel recherche dans sa base <strong>de</strong> données l’ensemble <strong>de</strong>s enregistrements<br />

correspondant <strong>et</strong> les présente <strong>de</strong> façon résumée à l’utilisateur sous la forme d’une<br />

liste<br />

3. L’utilisateur sélectionne l’enregistrement qui l’intéresse<br />

4. Le logiciel recherche dans sa base <strong>de</strong> données les données exhaustives <strong>de</strong><br />

l’enregistrement en question <strong>et</strong> le présente à l’utilisateur<br />

5. L’utilisateur peut alors consulter, modifier ou supprimer l’enregistrement<br />

6. En cas <strong>de</strong> modification ou <strong>de</strong> suppression, le logiciel m<strong>et</strong> à jour sa base <strong>de</strong> données<br />

La <strong>phase</strong> B peut se dérouler plusieurs jours après que la <strong>phase</strong> A se soit terminée.<br />

Bien que les fichiers perm<strong>et</strong>tent <strong>de</strong> mémoriser <strong>de</strong> l’information avec un ordinateur <strong>de</strong>puis <strong>de</strong><br />

longues années, ils ne suffisent pas en informatique <strong>de</strong> gestion. En eff<strong>et</strong>, les données sont<br />

susceptibles d’être accédées simultanément par plusieurs utilisateurs <strong>et</strong> le mécanisme <strong>de</strong><br />

verrouillage <strong>de</strong>s fichiers offert par les systèmes d’exploitation n’est pas assez <strong>fin</strong> puisqu’un<br />

fichier ne peut être manipulé que par un utilisateur à la fois. C’est pourquoi il existe <strong>de</strong>s<br />

logiciels spécialisés pour assurer la persistance d’informations, les systèmes <strong>de</strong> gestion <strong>de</strong><br />

base <strong>de</strong> données (SGBD).<br />

Un SGBD utilise bien <strong>de</strong>s fichiers pour le stockage <strong>de</strong>s informations, mais celles-ci sont<br />

présentées aux applications clientes sous une forme complètement différente <strong>et</strong> indépendante.<br />

Les données gérées par un SGBD sont accessibles au moyen d’un langage <strong>de</strong> haut niveau non<br />

procé<strong>du</strong>ral, le langage SQL. Ce <strong>de</strong>rnier perm<strong>et</strong> d’insérer, <strong>de</strong> modifier, <strong>de</strong> supprimer <strong>et</strong> <strong>de</strong><br />

22.06.2005 2/78


sélectionner <strong>de</strong>s informations mémorisées par un SGBD dans un environnement logiciel<br />

client-serveur.<br />

1.5. Applications clientes<br />

Depuis l’arrivée à maturité <strong>de</strong> l’approche obj<strong>et</strong> dans le courrant <strong>de</strong>s années 90, la majorité <strong>de</strong>s<br />

applications qui accè<strong>de</strong>nt aux SGBD sont désormais réalisées avec un langage <strong>de</strong><br />

programmation orienté obj<strong>et</strong>.<br />

Initialement, le modèle obj<strong>et</strong> à la base <strong>de</strong> ces langages, <strong>de</strong>vait être la solution à la fameuse<br />

crise <strong>du</strong> logiciel <strong>de</strong>s années 1970 <strong>et</strong> par conséquent perm<strong>et</strong>tre aux programmeurs d’écrire <strong>de</strong>s<br />

logiciels <strong>de</strong> qualité. Cependant au fil <strong>du</strong> temps, il a été utilisé par les divers acteurs <strong>du</strong> mon<strong>de</strong><br />

informatique à d’autres <strong>fin</strong>s <strong>et</strong> notamment par les constructeurs <strong>de</strong> SGBD pour assurer la<br />

persistance d’informations.<br />

Les langages <strong>de</strong> programmation obj<strong>et</strong> sont actuellement très prisés car ils perm<strong>et</strong>tent d’écrire<br />

<strong>du</strong> co<strong>de</strong> satisfaisant très bien aux critères <strong>du</strong> génie logiciel, notamment la réutilisabilité <strong>et</strong><br />

l’évolutivité. De plus, la création d’interfaces graphiques (GUI) est gran<strong>de</strong>ment simplifiée<br />

avec ces langages. En eff<strong>et</strong>, l’encapsulation <strong>de</strong>s données <strong>et</strong> <strong>de</strong>s traitements <strong>et</strong> l’héritage<br />

perm<strong>et</strong>tent le développement <strong>de</strong> librairies graphiques dont les obj<strong>et</strong>s (fenêtres, boutons,<br />

ascenseurs, …) sont facilement appréhendables <strong>et</strong> utilisables par les développeurs.<br />

1.6. Anomalie d’impédance<br />

Il faut bien comprendre qu’un langage <strong>de</strong> programmation obj<strong>et</strong> <strong>et</strong> qu’un SGBD n’ont pas les<br />

mêmes <strong>fin</strong>alités <strong>et</strong> que leurs modèles <strong>de</strong> données ne sont par conséquent pas i<strong>de</strong>ntiques. Le<br />

premier doit perm<strong>et</strong>tre la pro<strong>du</strong>ction <strong>de</strong> co<strong>de</strong> réutilisable <strong>et</strong> évolutif alors que le second doit<br />

garantir la cohérence d’informations persistantes.<br />

Malheureusement les langages <strong>de</strong> programmation orientés obj<strong>et</strong> ne prennent pas en compte,<br />

<strong>de</strong> façon native, la persistance <strong>de</strong>s obj<strong>et</strong>s métier dans les SGBD. En eff<strong>et</strong>, comme les<br />

principes <strong>de</strong> modélisation ne sont pas i<strong>de</strong>ntiques entre le modèle obj<strong>et</strong> <strong>et</strong> le modèle <strong>du</strong> SGBD,<br />

la mise en correspondance <strong>de</strong>s <strong>de</strong>ux n’est pas vraiment simple à réaliser <strong>et</strong> pose problème. Le<br />

terme d’ « anomalie d’impédance » est fréquent utilisé dans la littérature pour exprimer c<strong>et</strong>te<br />

inadéquation.<br />

Pour travailler avec un SGBD <strong>de</strong>puis un langage obj<strong>et</strong>, il faut donc se résoudre à recourir à<br />

<strong>de</strong>s librairies spécialisées qui perm<strong>et</strong>tent d’embarquer <strong>de</strong>s instructions SQL (JDBC, SQLJ, …)<br />

dans les obj<strong>et</strong>s ou à utiliser <strong>de</strong>s logiciels <strong>de</strong> mise en correspondance (Castor, JDO, …).<br />

1.7. Mapping obj<strong>et</strong> – relationnel<br />

Dans le cadre <strong>de</strong> ce proj<strong>et</strong>, nous avons dû choisir une solution pour la mise en correspondance<br />

<strong>du</strong> modèle obj<strong>et</strong> <strong>et</strong> <strong>du</strong> modèle relationnel. Comme l’objectif <strong>du</strong> proj<strong>et</strong> est <strong>de</strong> concevoir un<br />

générateur perm<strong>et</strong>tant d’assurer la persistance <strong>et</strong> l’intégrité <strong>de</strong>s obj<strong>et</strong>s métier, nous avons<br />

22.06.2005 3/78


<strong>et</strong>enu une solution <strong>de</strong> mapping qui n’offre aucune possibilité <strong>de</strong> personnalisation <strong>de</strong> la mise<br />

en correspondance.<br />

Notre solution consiste donc à dire que pour chaque classe Java il existe un type Oracle<br />

correspondant dans la base <strong>de</strong> données. Une table obj<strong>et</strong> est construite à partir <strong>du</strong> type Oracle<br />

pour assurer la persistance <strong>et</strong> l’intégrité <strong>de</strong>s instances.<br />

La classe Java possè<strong>de</strong> exactement les mêmes attributs que le type Oracle. La seule chose qui<br />

change entre les <strong>de</strong>ux c’est le langage <strong>de</strong> spécification.<br />

public class Client {<br />

}<br />

private int numero;<br />

private String nom;<br />

private Adresse adresse;<br />

private ListeTelephones telephones;<br />

22.06.2005 4/78<br />

CREATE TYPE client AS OBJECT (<br />

)<br />

numero NUMBER,<br />

nom VARCHAR2(255),<br />

adresse ADRESSE<br />

telephones LISTTELEPHONES<br />

Notre solution nous amène donc à pro<strong>du</strong>ire <strong>de</strong>s règles <strong>de</strong> tra<strong>du</strong>ction pour les types <strong>de</strong> bases<br />

(dans l’exemple int -> NUMBER, String -> VARCHAR2(255)) par contre les attributs<br />

composé (adresse) <strong>et</strong> les collections (telephones) sont mise en correspondance <strong>de</strong> façon<br />

directe puisque les <strong>de</strong>ux langages supportent ces types d’attribut.<br />

Ce type <strong>de</strong> mapping nous perm<strong>et</strong>tra d’utiliser un outil comme JPublisher d’Oracle qui offre<br />

déjà l’automatisation <strong>de</strong> la transformation <strong>de</strong> types Oracle en classes Java. Nous pourrons<br />

ainsi nous concentrer sur la génération <strong>de</strong>s règles d’intégrité qui est la partie la plus<br />

intéressante <strong>de</strong> ce proj<strong>et</strong> <strong>et</strong> celle qui amène le plus <strong>de</strong> valeur ajoutée en terme <strong>de</strong> Ra&D.<br />

1.8. Sources <strong>de</strong> dé<strong>fin</strong>ition<br />

A l’origine <strong>du</strong> proj<strong>et</strong>, il était question <strong>de</strong> générer <strong>du</strong> co<strong>de</strong> SQL-DDL à partir <strong>de</strong>s méta-données<br />

<strong>de</strong>s classes Java issues <strong>de</strong>s <strong>phase</strong>s d’analyse <strong>et</strong> <strong>de</strong> conception d’un proj<strong>et</strong> informatique.<br />

Malheureusement, la sémantique <strong>de</strong> Java n’est pas assez riche pour exprimer toute la<br />

sémantique d’un modèle notamment en ce qui concerne les associations entre classes <strong>et</strong> les<br />

invariants <strong>de</strong> classes (contraintes).<br />

En eff<strong>et</strong>, il n’est pas possible en Java <strong>de</strong> spécifier si une relation entre <strong>de</strong>ux classes est une<br />

association, une agrégation ou une composition. C<strong>et</strong>te distinction est importante notamment<br />

entre l’association <strong>et</strong> la composition pour perm<strong>et</strong>tre à un générateur <strong>de</strong> co<strong>de</strong> SQL-DDL <strong>de</strong><br />

créer correctement le schéma <strong>de</strong> données.<br />

A partir <strong>de</strong>s <strong>de</strong>ux classes ci-<strong>de</strong>ssous, nous pouvons déterminer qu’une instance <strong>de</strong> A ne peut<br />

être associée au maximum qu’à une seule instance <strong>de</strong> B alors qu’une instance <strong>de</strong> B peut être<br />

associées au maximum à plusieurs instances <strong>de</strong> A. Par contre, il ne nous est pas possible <strong>de</strong><br />

savoir si la relation entre elles est une association ou une composition. Les multiplicités<br />

minimales (0 ou 1) ne sont également pas i<strong>de</strong>ntifiables à partir <strong>du</strong> co<strong>de</strong> Java.


public class A {<br />

}<br />

private Integer numero;<br />

private B unB;<br />

public A(Integer numero) {<br />

this.numero = numero;<br />

}<br />

public Integer g<strong>et</strong>Numero() {<br />

r<strong>et</strong>urn numero;<br />

}<br />

public void s<strong>et</strong>B(B unB) {<br />

this.unB = unB;<br />

}<br />

public B g<strong>et</strong>B() {<br />

r<strong>et</strong>urn unB;<br />

}<br />

22.06.2005 5/78<br />

public class B {<br />

}<br />

private Integer numero;<br />

private java.util.Map <strong>de</strong>sA;<br />

public B(Integer numero) {<br />

this.numero = numero;<br />

<strong>de</strong>sA = new java.util.HashMap();<br />

}<br />

public Integer g<strong>et</strong>Numero() {<br />

r<strong>et</strong>urn numero;<br />

}<br />

public void addA(A unA) {<br />

<strong>de</strong>sA.put(unA.g<strong>et</strong>Numero(),<br />

unA);<br />

}<br />

public A g<strong>et</strong>UnA(Integer numero) {<br />

r<strong>et</strong>urn (A)<strong>de</strong>sA.g<strong>et</strong>(numero);<br />

}<br />

Nous avons donc dû nous tourner vers un langage <strong>de</strong> spécification plus riche. Nous nous<br />

sommes donc tout naturellement tournés vers le langage UML. Il est possible grâce à la<br />

spécification XMI <strong>de</strong> l’OMG <strong>de</strong> créer un fichier XML contenant la <strong>de</strong>scription d’un modèle<br />

UML.<br />

La source <strong>de</strong> dé<strong>fin</strong>ition <strong>de</strong> notre générateur sera donc un fichier XMI <strong>et</strong> non plus un ensemble<br />

<strong>de</strong> classes Java.<br />

Nous avons repro<strong>du</strong>it ci-<strong>de</strong>ssous une partie <strong>du</strong> fichier XMI décrivant le même modèle que le<br />

modèle Java étudié précé<strong>de</strong>mment. Nous avons volontairement laissé <strong>de</strong> côté les métho<strong>de</strong>s<br />

qui n’ont pas d’influence pour le proj<strong>et</strong>.<br />

<br />

<br />

<br />

<br />

//Type <strong>de</strong> données <strong>de</strong> l’attribut<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

//Type <strong>de</strong> données <strong>de</strong> l’attribut<br />

<br />

<br />

<br />

<br />

<br />

<br />


<br />

<br />

<br />

<br />

<br />

<br />

<br />

//Classe associée<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

//Classe associée<br />

<br />

<br />

<br />

<br />

//Type <strong>de</strong> données<br />

Grâce à la richesse sémantique d’UML <strong>et</strong> à XMI, nous avons maintenant à disposition toutes<br />

les informations qui nous manquaient dans le langage Java.<br />

Il manque encore quelque chose à notre source <strong>de</strong> dé<strong>fin</strong>ition pour être satisfaisante. En eff<strong>et</strong><br />

UML ne prend pas en charge l’expression <strong>de</strong> contraintes qui ne découlent pas <strong>de</strong> la<br />

sémantique <strong>de</strong> son méta-modèle.<br />

Nous allons prendre un exemple pour mieux comprendre ce problème. Nous aimerions<br />

exprimer que l’attribut « note » <strong>de</strong> la classe « Evaluation » peut contenir que <strong>de</strong>s valeurs<br />

entières comprises entre 1 <strong>et</strong> 10. Le type <strong>de</strong> données ne nous pose pas <strong>de</strong> problème avec UML<br />

puisqu’il suffit <strong>de</strong> dire que l’attribut est <strong>de</strong> type entier. Par contre la plage <strong>de</strong> valeurs [1,10] ne<br />

peut pas être représentée.<br />

Notre solution consiste à utiliser un langage formel d’expression <strong>de</strong> contraintes, le langage<br />

OCL <strong>de</strong> l’OMG pour exprimer notre règle métier.<br />

context Evaluation inv :<br />

note >= 1 and note


Dans un premier temps, nous avons utilisé l’outil <strong>de</strong> modélisation Rational Rose <strong>de</strong> Rational<br />

Software (www.rational.com) pour générer <strong>de</strong>s fichiers XMI. Ce type d’exportation n’étant<br />

pas offert en standard il faut recourir à un add-in pour cela. Nous avons cependant dû<br />

renoncer à utiliser Rational Rose car celui-ci ne perm<strong>et</strong> pas d’associer une contrainte OCL à<br />

une classe. Notre choix s’est <strong>fin</strong>alement porté sur Poseidon for UML <strong>de</strong> la société Gentleware<br />

(www.gentleware.com).<br />

Poseidon for UML sauvegar<strong>de</strong> ses modèles <strong>de</strong> façon native dans <strong>de</strong>s fichiers XMI. Un proj<strong>et</strong><br />

réalisé avec c<strong>et</strong> outil comporte plusieurs fichiers (notamment notre fameux fichier XMI) . Ces<br />

<strong>de</strong>rniers sont sauvegardés dans un fichier d’archive dont l’extension est zargo. Il suffit <strong>de</strong><br />

désarchiver un <strong>de</strong> ces fichiers <strong>de</strong> proj<strong>et</strong> avec un utilitaire comme Winzip pour accé<strong>de</strong>r au<br />

fichier XMI.<br />

22.06.2005 7/78<br />

!


Notre générateur <strong>de</strong>vra faire la différence entre les classes persistantes <strong>et</strong> les classes<br />

éphémères. Dans ce cas nous utiliserons une <strong>de</strong>s possibilités d’extension d’UML, les Tagged<br />

Values. Ce mécanisme perm<strong>et</strong> d’ajouter <strong>de</strong>s propriétés à un élément <strong>du</strong> méta-mo<strong>de</strong>l UML<br />

sans <strong>de</strong>voir modifier ce <strong>de</strong>rnier. La norme UML précise bien qu’une classe persistante doit<br />

être spécifiée au moyen d’une Tagged Value.<br />

Voici un aperçu simplifié <strong>du</strong> contenu <strong>du</strong> fichier XMI pro<strong>du</strong>it par Poseidon for UML :<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

22.06.2005 8/78<br />

!


<br />

<br />

<br />

1.9. Cible Relationnelle obj<strong>et</strong><br />

Le modèle relationnel a fait ses preuves <strong>et</strong> il a démontré, surtout <strong>de</strong>puis les années 80,<br />

qu'il avait <strong>de</strong>s points forts indiscutables. Il a aussi un certain nombre <strong>de</strong> points faibles,<br />

auxquels le modèle obj<strong>et</strong> répond assez bien, d'où l'intérêt d'une intégration en douceur<br />

<strong>de</strong>s <strong>de</strong>ux modèles.<br />

1.9.1. Forces <strong>et</strong> faiblesses <strong>du</strong> modèle relationnel<br />

Le modèle relationnel est complètement adapté aux applications <strong>de</strong> gestion grâce à son<br />

système <strong>de</strong> modélisation formé <strong>de</strong> tables dont les colonnes prennent <strong>de</strong>s valeurs<br />

alphanumériques. Les concepts <strong>du</strong> modèle relationnel (tables, enregistrements, relations,<br />

champs, <strong>et</strong>c…) sont simples <strong>et</strong> aisément compréhensibles. De plus, la longue expérience<br />

dont bénéficient maintenant les SGBD relationnels a permis <strong>de</strong> les optimiser <strong>et</strong> donc <strong>de</strong><br />

les rendre très performants.<br />

Un autre point fort <strong>du</strong> modèle relationnel est l'existence <strong>de</strong> SQL, un langage standardisé<br />

<strong>de</strong> création <strong>et</strong> <strong>de</strong> manipulation <strong>de</strong>s bases <strong>de</strong> données. Le langage SQL est bien adapté<br />

aux architectures client-serveur, il intègre la gestion <strong>de</strong>s transactions, indispensable lors<br />

d'accès concurrents aux données ainsi que pour leur sécurité.<br />

Par contre, le modèle relationnel, dont la conception est bien antérieure à l'avènement <strong>du</strong><br />

multimédia <strong>et</strong> d'Intern<strong>et</strong>, présente certaines faiblesses qui le pénalise aujourd'hui. On<br />

peut citer en particulier.<br />

• Pas <strong>de</strong> support <strong>de</strong>s obj<strong>et</strong>s complexes<br />

C<strong>et</strong>te contrainte, imposée par le respect <strong>de</strong> la première forme normale <strong>de</strong> Boyce-Codd1,<br />

est inadaptée à la gestion <strong>de</strong>s obj<strong>et</strong>s complexes, <strong>de</strong> plus en plus nombreux dans les<br />

applications actuelles. L'intro<strong>du</strong>ction <strong>de</strong>s types <strong>de</strong> données binaires comme les CLOB<br />

(Character Large Object) ou les BLOB (Binary Large Object) ne résoud pas le problème,<br />

car la nature <strong>du</strong> stockage <strong>de</strong> ces types dans les SGBD relationnels ne perm<strong>et</strong> pas <strong>de</strong>s<br />

opérations comme la comparaison <strong>de</strong> <strong>de</strong>ux LOB. Ils ne sont pas structurés, ce qui impose<br />

une lecture séquentielle <strong>de</strong> l'obj<strong>et</strong>.<br />

• Non intégration <strong>de</strong>s traitements:<br />

Le modèle relationnel sépare complètement les données <strong>de</strong>s traitements, ce qui rend<br />

impossible l'encapsulation <strong>de</strong>s données. L'encapsulation perm<strong>et</strong> <strong>de</strong> cacher certaines<br />

informations à l'utilisateur <strong>et</strong> <strong>de</strong> les rendre accessibles uniquement par <strong>de</strong>s opérations ou<br />

fonctions manipulant ces informations, perm<strong>et</strong>tant un contrôle <strong>de</strong> la consistance <strong>de</strong>s<br />

données par le programme.<br />

• Absence <strong>de</strong> pointeurs visibles:<br />

Les pointeurs perm<strong>et</strong>tent un parcours très rapi<strong>de</strong> <strong>de</strong> gran<strong>de</strong>s quantités <strong>de</strong> données, avec<br />

<strong>de</strong>s gains importants par rapport aux jointures par valeurs utilisées avec le modèle<br />

1 La première forme normale veut que chaque attribut (ou colonne) d'une table contienne une valeur unique pour<br />

chaque enregistrement.<br />

22.06.2005 9/78


elationnel. Il est aussi possible <strong>de</strong> les utiliser pour partager <strong>de</strong>s références sur <strong>de</strong>s<br />

obj<strong>et</strong>s volumineux <strong>et</strong> ainsi économiser <strong>de</strong> l'espace <strong>de</strong> stockage. La majorité <strong>de</strong>s critiques<br />

liées aux pointeurs sont justifiées, mais il serait dommage <strong>de</strong> se priver <strong>de</strong> leurs<br />

avantages au niveau <strong>de</strong>s SGBD, uniquement à cause <strong>de</strong> ces critiques, d'autant plus que<br />

les problèmes qui leurs sont liés sont connus, <strong>et</strong> donc évitables.<br />

1.9.2. Apports <strong>du</strong> modèle obj<strong>et</strong><br />

• L'i<strong>de</strong>ntité d'obj<strong>et</strong>:<br />

L’i<strong>de</strong>ntité d’obj<strong>et</strong> appelé OID (Object I<strong>de</strong>ntifier) perm<strong>et</strong> <strong>de</strong> référencer <strong>de</strong> manière unique<br />

dans une base <strong>de</strong> données n'importe quel obj<strong>et</strong> <strong>de</strong> c<strong>et</strong>te base. Il perm<strong>et</strong> aussi l'utilisation<br />

<strong>de</strong> pointeurs sur l'obj<strong>et</strong>. Ces pointeurs perm<strong>et</strong>tent <strong>de</strong> créer <strong>de</strong>s structures complexes<br />

d'obj<strong>et</strong>s (graphes, chaînes) <strong>et</strong> aussi <strong>de</strong> parcourir <strong>de</strong>s suites d'associations très<br />

rapi<strong>de</strong>ment car elles ne <strong>de</strong>man<strong>de</strong>nt plus l'utilisation <strong>de</strong> jointures longues <strong>et</strong> coûteuses.<br />

• L'encapsulation <strong>de</strong>s données:<br />

L’encapsulation a pour but <strong>de</strong> présenter une structure <strong>de</strong> données stable à l'utilisateur,<br />

même si la structure interne <strong>de</strong> la base change complètement. Les données, au lieu<br />

d'être directement accessible par l'utilisateur, sont cachées <strong>et</strong> <strong>de</strong>s métho<strong>de</strong>s perm<strong>et</strong>tant<br />

la lecture <strong>et</strong> la modification sont mises en place.<br />

C<strong>et</strong>te couche d'abstraction entre les données <strong>et</strong> l'utilisateur facilite gran<strong>de</strong>ment la tâche<br />

<strong>du</strong> programmeur, qui peut gérer comme il le désire son application en interne avec pour<br />

seule contrainte la fourniture d'une interface stable à l'utilisateur.<br />

• L'héritage:<br />

L’héritage perm<strong>et</strong> la réutilisation <strong>de</strong>s types <strong>de</strong> données, car il perm<strong>et</strong> la dé<strong>fin</strong>ition<br />

d'obj<strong>et</strong>s génériques (tables, types <strong>de</strong> données abstraits) pouvant être spécialisés suivant<br />

les utilisations. Il facilite le travail <strong>du</strong> développeur qui ne doit plus se soucier <strong>de</strong>s détails<br />

d'implémentation pour chaque obj<strong>et</strong>.<br />

1.9.3. Le modèle obj<strong>et</strong>-relationnel<br />

Le modèle obj<strong>et</strong>-relationnel se fon<strong>de</strong> sur l'extension <strong>du</strong> modèle relationnel par les<br />

concepts essentiels <strong>de</strong> l'obj<strong>et</strong>. Le cœur <strong>du</strong> système reste donc relationnel, mais tous les<br />

concepts clés <strong>de</strong> l'obj<strong>et</strong> y sont ajoutés dans une forme particulièrement prévue pour<br />

faciliter l'intégration <strong>de</strong>s <strong>de</strong>ux modèles. On peut citer en particulier, le support <strong>de</strong>s obj<strong>et</strong>s<br />

complexes qui est sans aucun doute, l'apport le plus important <strong>de</strong> ce modèle. Il a été<br />

intro<strong>du</strong>it pour perm<strong>et</strong>tre le support <strong>de</strong>s types <strong>de</strong> données ne respectant pas la première<br />

forme normale <strong>de</strong> Boyce-Codd, aussi appelé NF 2 (Not First Normal Form). Ainsi tous les<br />

types <strong>de</strong> données multimédias peuvent aussi être considérés comme <strong>de</strong>s types <strong>de</strong><br />

données complexes, par exemple <strong>de</strong>s données cartographiques ou géométriques<br />

nécessitent <strong>de</strong>s colonnes <strong>de</strong> tables capables <strong>de</strong> stocker <strong>de</strong>s listes <strong>de</strong> points.<br />

Faisant suite à la proposition <strong>du</strong> modèle persistant obj<strong>et</strong> appelé manifeste, le modèle<br />

relationnel obj<strong>et</strong> est principalement basé sur <strong>de</strong>ux références incontournables.<br />

Le second manifeste ou contre-manifeste, dont le principal auteur, Stonebraker place les<br />

SGBD obj<strong>et</strong>s comme ne possédant pas <strong>de</strong> langage d'interrogation.<br />

Dans le troisième manifeste, Date <strong>et</strong> Darwen proposent une base théorique à<br />

l'intégration <strong>de</strong>s concepts obj<strong>et</strong>s dans un contexte relationnel. Ils affirment que<br />

l'utilisation <strong>de</strong> pointeurs dans les bases <strong>de</strong> données obj<strong>et</strong>-relationnelles brise la notion<br />

22.06.2005 10/78


d'intégrité référentielle. L'avis général sur c<strong>et</strong>te affirmation est moins tranché, même s'il<br />

est clair pour tout le mon<strong>de</strong> que les pointeurs ne sont pas l'outil idéal pour la gestion <strong>de</strong><br />

l'intégrité référentielle.<br />

C<strong>et</strong>te proposition <strong>de</strong>vrait débouché sur une normalisation sous la forme <strong>de</strong> la nouvelle<br />

norme SQL 3 (Structured Query Language, ou langage structuré <strong>de</strong> requêtes), qui<br />

contiendra <strong>de</strong> nombreuses portions consacrées à la technologie obj<strong>et</strong>-relationnelle.<br />

1.9.3.1. Les nouveaux concepts <strong>du</strong> modèle RO<br />

• Types <strong>de</strong> données utilisateurs<br />

Type <strong>de</strong> données dé<strong>fin</strong>issable par l'utilisateur composé<br />

d'une structure <strong>de</strong> données <strong>et</strong> d'opérations encapsulant<br />

c<strong>et</strong>te structure<br />

Le système <strong>de</strong> types <strong>du</strong> SGBD <strong>de</strong>vient extensible <strong>et</strong> n'est plus limité aux types<br />

alphanumériques <strong>de</strong> base, l'utilisateur est en mesure <strong>de</strong> dé<strong>fin</strong>ir ses propres types,<br />

adaptés à la gestion <strong>de</strong> ses informations, soit image, point, vecteur, <strong>et</strong>c. Ils sont appelés<br />

types abstraits (ADT, Abstract Data Type), ce nom vient <strong>du</strong> fait que l'implémentation <strong>du</strong><br />

type est spécifique à l'environnement <strong>et</strong> que seule son interface est visible.<br />

• Patrons <strong>de</strong> collections (Collection template)<br />

Type <strong>de</strong> données générique perm<strong>et</strong>tant <strong>de</strong> supporter <strong>de</strong>s<br />

attributs multivalués <strong>et</strong> <strong>de</strong> les organiser selon un type <strong>de</strong><br />

collection.<br />

Les patrons <strong>de</strong> listes perm<strong>et</strong>tent <strong>de</strong> dé<strong>fin</strong>ir <strong>de</strong>s nouveaux types sur la base <strong>de</strong> collections<br />

d'autres types. Ils peuvent utiliser les différents types <strong>de</strong> collections <strong>du</strong> modèle obj<strong>et</strong>relationnel,<br />

comme table, liste, ensemble <strong>et</strong> tableau dynamique.<br />

• Référence d'obj<strong>et</strong><br />

Type <strong>de</strong> données particulier perm<strong>et</strong>tant <strong>de</strong> mémoriser<br />

l'adresse invariante d'un obj<strong>et</strong> ou d'un tuple<br />

Les références sont les i<strong>de</strong>ntificateurs d'obj<strong>et</strong> (OID) <strong>du</strong> modèle obj<strong>et</strong>-relationnel. Elles<br />

représentent <strong>de</strong>s valeurs uniques <strong>et</strong> invariantes perm<strong>et</strong>tant <strong>de</strong> chaîner les obj<strong>et</strong>s entre<br />

eux sans passer par <strong>de</strong>s jointures par valeurs.<br />

• Héritage <strong>de</strong> type<br />

Forme d'héritage impliquant la possibilité <strong>de</strong> dé<strong>fin</strong>ir un<br />

sous-type d'un type existant, celui-ci héritant alors <strong>de</strong> la<br />

structure <strong>et</strong> <strong>de</strong>s opérations <strong>du</strong> type <strong>de</strong> base<br />

Il est à noter que l'obj<strong>et</strong>-relationnel perm<strong>et</strong> aussi l'héritage <strong>de</strong> table car une table est vue<br />

comme un type sans opération.<br />

1.10. Choix d’une plateforme cible<br />

La technologie obj<strong>et</strong>-relationnelle est née en 1992, elle est donc assez nouvelle sur le<br />

marché <strong>de</strong>s SGBD, dominé <strong>de</strong>puis environ 1970 par les bases <strong>de</strong> données <strong>de</strong> type<br />

22.06.2005 11/78


elationnel. Actuellement, tous les grands éditeurs <strong>de</strong> SGBD sont conscients <strong>de</strong>s limites<br />

<strong>du</strong> modèle relationnel, ils ont donc vu dans le modèle obj<strong>et</strong>-relationnel une manière<br />

d'enrichir ce modèle. Informix a été le premier éditeur <strong>de</strong> SGBD à relever le défi <strong>de</strong><br />

l'obj<strong>et</strong>-relationnel en rach<strong>et</strong>ant la firme Illustra, qui développait alors une version<br />

commerciale <strong>du</strong> système Postgres, un SGBD relationnel éten<strong>du</strong>. Les autres grands<br />

éditeurs <strong>de</strong> SGBD, comme IBM <strong>et</strong> Oracle, ont suivi c<strong>et</strong>te évolution, <strong>et</strong> la tendance<br />

générale chez ces éditeurs se décompose actuellement en trois pans:<br />

• Evolution interne <strong>du</strong> moteur <strong>du</strong> SGBD.<br />

• Connexion entre le moteur relationnel <strong>et</strong> <strong>de</strong>s moteurs spécialisés dans la<br />

manipulation <strong>de</strong> certains types <strong>de</strong> données complexes.<br />

• Promotion <strong>de</strong>s solutions Middleware qui perm<strong>et</strong>tent l'interconnexion <strong>de</strong>s applications<br />

à <strong>de</strong>s SGBD hétérogènes.<br />

L’étu<strong>de</strong> concernant le choix <strong>de</strong> plate-forme cible s’est arrêtée sur un a priori <strong>de</strong> <strong>de</strong>ux<br />

constructeurs.<br />

1.10.1. PostgreSQL<br />

PostreSQL est le système <strong>de</strong> gestion <strong>de</strong> base <strong>de</strong> données académique par excellence. On<br />

trouve sur le N<strong>et</strong> plusieurs documents <strong>de</strong> qualité sur ce système, mais nous n’avons pas<br />

trouvé <strong>de</strong> références rigoureuses traitant <strong>de</strong> l’aspect relationnel obj<strong>et</strong>. Nous avons étudié<br />

les diverses fonctionnalités <strong>et</strong> développé un p<strong>et</strong>it prototype. Ce SGBD supporte <strong>de</strong>puis<br />

plusieurs années <strong>de</strong>s concepts comme l’héritage mais les métho<strong>de</strong>s <strong>et</strong> plus graves les<br />

types abstrait <strong>de</strong> données ne sont pas supportés. A la <strong>fin</strong> <strong>de</strong> c<strong>et</strong>te brève étu<strong>de</strong> nous<br />

avons abandonné ce pro<strong>du</strong>it.<br />

1.10.2. Oracle<br />

Oracle propose <strong>de</strong>puis sa version 8 <strong>de</strong>s fonctionnalités relationnelles obj<strong>et</strong> qui ont été<br />

améliorée avec sa version 9 qui supporte notamment l’héritage. Nous avons déjà <strong>de</strong>s<br />

compétences sur ce pro<strong>du</strong>it, <strong>et</strong> concernant la partie relationnelle obj<strong>et</strong>, le proj<strong>et</strong> ISN<strong>et</strong> 15<br />

« base <strong>de</strong> données relationnelles obj<strong>et</strong> » déposé dans le cadre <strong>de</strong> la réserve stratégique<br />

<strong>de</strong> la HES-So constitue une sérieuse base <strong>de</strong> référence en plus <strong>de</strong> la large documentation<br />

fournies par <strong>de</strong>s tiers.<br />

Les groupes <strong>de</strong> compétences ISN<strong>et</strong> <strong>de</strong> Neuchâtel <strong>et</strong> <strong>de</strong> Genève disposent tous les <strong>de</strong>ux<br />

<strong>de</strong> plate-formes fonctionnelles avec ce constructeur.<br />

Description <strong>de</strong>s composants<br />

1.11. OCL<br />

1.11.1. Intro<strong>du</strong>ction<br />

OCL (Object Constraint Language) est un langage formel pour l’expression <strong>de</strong> contraintes,<br />

standardisé par l’OMG.<br />

Une expression OCL est sans eff<strong>et</strong> <strong>de</strong> bord ; elle ne modifie pas l’état <strong>du</strong> système.<br />

L’exécution d’une expression OCL ne fait que r<strong>et</strong>ourner une valeur.<br />

22.06.2005 12/78


OCL est utilisé pour exprimer les invariants <strong>du</strong> méta-modèle UML ainsi que les règles<br />

syntaxiques d’UML qui ne peuvent pas être exprimées dans le méta-modèle.<br />

OCL est un langage formel qui se veut facile à appréhen<strong>de</strong>r. Il a été conçu par la division<br />

« assurances » d’IBM comme langage <strong>de</strong> modélisation métier.<br />

OCL est un langage typé <strong>et</strong> par conséquent chaque expression possè<strong>de</strong> un type. Une<br />

expression OCL bien formée doit respecter les règles <strong>de</strong> conformité <strong>de</strong>s types <strong>du</strong> langage.<br />

Chaque classificateur dé<strong>fin</strong>it dans un modèle UML est un type OCL vali<strong>de</strong>.<br />

Les états <strong>de</strong>s obj<strong>et</strong>s d’un modèle ne peuvent pas changer pendant l’exécution d’une<br />

expression OCL.<br />

OCL peut être utilisé dans les cas suivants :<br />

• Spécification <strong>de</strong>s invariants <strong>de</strong>s classes <strong>et</strong> <strong>de</strong>s types d’un modèle <strong>de</strong> classes<br />

• Spécification <strong>de</strong>s invariants <strong>de</strong> type pour les stéréotypes<br />

• Description <strong>de</strong>s pré- <strong>et</strong> post-conditions d’une opération<br />

• Spécification <strong>de</strong>s contraintes d’une opération<br />

• Description <strong>de</strong>s gar<strong>de</strong>s<br />

• Expression <strong>de</strong>s navigations au travers d’un modèle <strong>de</strong> classes<br />

1.11.2. Mot-clé « context »<br />

Chaque expression OCL est liée à un contexte dé<strong>fin</strong>issant le type auquel elle se<br />

rapporte. Chaque instance d’un type doit ensuite respecter les contraintes dé<strong>fin</strong>ies<br />

pour ce type.<br />

Stéréotype <strong>de</strong> contrainte<br />

• inv = 0<br />

Il est possible <strong>de</strong> spécifier un nom d’instance.<br />

context p : Pile inv :<br />

p.nb_elem >= 0<br />

1.11.3. Mot-clé « package »<br />

Il est possible <strong>de</strong> préciser le contexte d’une expression OCL en indiquant un nom <strong>de</strong><br />

paqu<strong>et</strong>age auquel elle est rattachée. Un paqu<strong>et</strong>age peut contenir plusieurs<br />

expressions OCL.<br />

22.06.2005 13/78


package unPaqu<strong>et</strong>age::unSousPaqu<strong>et</strong>age<br />

context Pile inv :<br />

self.nb_elem >= 0<br />

endpackage<br />

L’opérateur :: est l’opérateur <strong>de</strong> résolution <strong>de</strong> portée <strong>du</strong> langage OCL.<br />

1.11.4. Mot-clé « self »<br />

Le mot-clé self sert à i<strong>de</strong>ntifier l’instance à laquelle la contrainte se rapporte. Il n’est<br />

pas obligatoire.<br />

context Pile inv :<br />

self.nb_elem >= 0<br />

1.11.5. Commentaires<br />

Les commentaires correspon<strong>de</strong>nt à <strong>du</strong> texte placé à la suite <strong>de</strong> <strong>de</strong>ux tir<strong>et</strong>s ; ils<br />

s’éten<strong>de</strong>nt jusqu’à la <strong>fin</strong> <strong>de</strong> la ligne.<br />

context Pile inv :<br />

self.nb_elem >= 0 -- nb_elem est positif ou nul<br />

Nommage <strong>de</strong>s contraintes<br />

Il est possible <strong>de</strong> nommer explicitement une contrainte a<strong>fin</strong> <strong>de</strong> pouvoir la réutiliser par<br />

la suite.<br />

context Pile inv maContraite :<br />

nb_elem >= 0<br />

Types <strong>de</strong> base<br />

Les types <strong>de</strong> base OCL sont les entiers, les booléens, les chaînes <strong>de</strong> caractères <strong>et</strong><br />

les réels.<br />

Type Valeurs<br />

Boolean true, false<br />

Integer 1, -5, 2, 34, 26524, …<br />

Real 1.5, 3.14, 100.987, -234.0, …<br />

String ‘Hello world’<br />

22.06.2005 14/78


Le type OclAny est le supertype pour tous les types.<br />

OCL dé<strong>fin</strong>it un certain nombre d’opérations pour les types <strong>de</strong> bases.<br />

Type Opérations<br />

Boolean =, and, or, xor, not, implies, if-then-elseendif<br />

Integer *, +, -, /, =, abs(), div(), mod(), max(), min()<br />

Real *, +, -, /, =, , , =, abs(), floor(),<br />

round(), max(), min()<br />

String =, size(), toUpper(), toLower(), concat(),<br />

substring()<br />

Types énumérés<br />

Un type énuméré est une classe avec le stéréotype « enumeration » dans un modèle<br />

UML. Une énumération est considérée comme un type <strong>de</strong> données<br />

contexte Personne inv :<br />

sexe = Sexe :: féminin<br />

Dé<strong>fin</strong>ition d’attributs <strong>et</strong> d’opérations<br />

<br />

Sexe<br />

masculin<br />

féminin<br />

Il est possible <strong>de</strong> dé<strong>fin</strong>ir <strong>de</strong>s attributs <strong>et</strong> <strong>de</strong>s opérations a<strong>fin</strong> <strong>de</strong> réutiliser plusieurs fois<br />

une expression OCL.<br />

context Person inv :<br />

l<strong>et</strong> income : Integer = job.salary -> sum()<br />

l<strong>et</strong> hasTitle(aTitle: String) : Boolean =<br />

job->exists(title = aTitle)<br />

in<br />

if isUnemployed then<br />

income < 100<br />

else<br />

income >= 100 and hasTitle(‘manager’)<br />

endif<br />

Un attribut ou une opération n’est visible qu’à l’intérieur <strong>de</strong> la contrainte qui la dé<strong>fin</strong>it.<br />

22.06.2005 15/78


Il est cependant possible <strong>de</strong> dé<strong>fin</strong>ir un attribut ou une opération visible par toutes les<br />

contraintes d’un contexte. Pour cela, il faut dé<strong>fin</strong>ir une contrainte stéréotypée<br />

« <strong>de</strong><strong>fin</strong>ition ». Une telle contrainte ne peut contenir que <strong>de</strong>s dé<strong>fin</strong>itions d’attributs <strong>et</strong><br />

d’opérations.<br />

context Person <strong>de</strong>f :<br />

l<strong>et</strong> income : Integer = job.salary -> sum()<br />

l<strong>et</strong> hasTitle(aTitle: String) : Boolean =<br />

job->exists(title = aTitle)<br />

context Person inv :<br />

if isUnemployed then<br />

income < 100<br />

else<br />

income >= 100 and hasTitle(‘manager’)<br />

endif<br />

Le nom d’un attribut ou d’une opération dé<strong>fin</strong>i par l<strong>et</strong> ne doit pas entrer en conflit<br />

avec le nom d’un attribut, d’une extrémité d’association ou d’une opération <strong>du</strong><br />

classificateur <strong>du</strong> contexte <strong>de</strong> la contrainte.<br />

Conformité <strong>de</strong>s types <strong>de</strong> base<br />

Type Opérations<br />

Integer Real<br />

Transtypage<br />

La fonction oclAsType(Type) perm<strong>et</strong> <strong>de</strong> faire un down cast (transtypage vers un<br />

sous-type).<br />

unClient.oclAsType(PersonneMorale)<br />

Règles <strong>de</strong> précé<strong>de</strong>nce<br />

1) @pre<br />

2) . -><br />

3) not -(unaire)<br />

4) * /<br />

5) + -(binaire)<br />

6) if-then-else-endif<br />

7) < > =<br />

8) = <br />

9) and or xor<br />

10) implies<br />

22.06.2005 16/78


Redé<strong>fin</strong>ition <strong>de</strong>s opérateurs<br />

Les opérateurs +, -, *, /, , , =, and, or, xor peuvent être redé<strong>fin</strong>is pour<br />

n’importe quel type <strong>de</strong> l’utilisateur.<br />

a + b a.+(b) T +(T)<br />

Liste <strong>de</strong>s mots-clés<br />

Propriétés<br />

if not xor context post<br />

then l<strong>et</strong> implies <strong>de</strong>f in<br />

else or endpackage inv<br />

endif and package pre<br />

Une propriété peut être un attribut, une extrémité d’association ou une opération<br />

sans eff<strong>et</strong> <strong>de</strong> bord (isQuery = true) d’un classificateur.<br />

L’accès à la valeur d’une propriété se fait au moyen <strong>de</strong> l’opérateur « . ».<br />

context Person inv :<br />

self.age > 0<br />

context Or<strong>de</strong>r inv :<br />

self.total() >= 0<br />

context xxx inv :<br />

self.yyy(z) = p<br />

Remarques : L’emploi <strong>de</strong>s parenthèses est obligatoire même si une opération n’a<br />

pas <strong>de</strong> paramètre.<br />

L’emploi <strong>du</strong> mot self est facultatif.<br />

Opérations <strong>et</strong> post-condition<br />

Lorsqu’une contrainte est dé<strong>fin</strong>ie comme une post-condition d’une opération, il est<br />

possible <strong>de</strong> faire référence au résultat <strong>de</strong> l’opération au moyen <strong>du</strong> mot « result ».<br />

context Person::income(d:Date) post :<br />

result = age * 1000<br />

Pour obtenir la valeur avant modification d’une propriété dans une post-condition, il<br />

faut post-fixer le nom <strong>de</strong> la propriété avec @pre.<br />

22.06.2005 17/78


context Mongolfiere.lacherLest(quantite : Poids) post :<br />

self.poids = self.poids@pre - quantite<br />

context Company ::hireEmployee(p : Person)<br />

pre: not employee->inclu<strong>de</strong>(p)<br />

post: employee->inclu<strong>de</strong>(p) and<br />

stockprice() = stockprice@pre() + 10<br />

Opérateur d’implication<br />

A implies B Si A est faux la condition est vraie<br />

Si A est vrai <strong>et</strong> B est vrai, la condition est vraie<br />

Si A est vrai <strong>et</strong> B est faux, la condition est fausse<br />

context Personne inv :<br />

estUnCon<strong>du</strong>cteur = vrai implies age > 18<br />

Opérations prédé<strong>fin</strong>ies<br />

OCL dé<strong>fin</strong>it cinq opérations qui peuvent être appliquées à tous les obj<strong>et</strong>s.<br />

oclInState<br />

Syntaxe : oclInState(s : oclState) : booléen<br />

L’expression est vraie si l’obj<strong>et</strong> est dans l’état « s » sinon elle est fausse. Les valeurs <strong>de</strong> « s »<br />

sont les noms <strong>de</strong>s états dé<strong>fin</strong>is dans l’automate d’états associé au classificateur <strong>de</strong> l’obj<strong>et</strong>. Le<br />

symbole « :: » perm<strong>et</strong> <strong>de</strong> présenter <strong>de</strong>s états imbriqués (<strong>et</strong>at_parent ::<strong>et</strong>at_enfant).<br />

oclIsNew<br />

Syntaxe : oclIsNew : booléen<br />

C<strong>et</strong>te expression est utilisée dans une post-condition ; elle est vraie si l’obj<strong>et</strong> est créé<br />

lors <strong>de</strong> l’exécution <strong>de</strong> l’opération.<br />

oclAsType<br />

Syntaxe : oclAsType(t : oclType) : instance d’oclType<br />

22.06.2005 18/78


C<strong>et</strong>te fonction perm<strong>et</strong> <strong>de</strong> faire <strong>de</strong>s conversions <strong>de</strong> type. Le type vers lequel se fait la<br />

conversion doit être un sous-type <strong>du</strong> type <strong>de</strong> l’obj<strong>et</strong> à convertir (down-cast). Comme<br />

dans tous langage, le down-cast est dangereux <strong>et</strong> doit être utilisé <strong>de</strong> façon réfléchie.<br />

unChien.oclAsType(ChienChasse)<br />

oclIsTypeOf<br />

Syntaxe : oclIsTypeOf(t : oclType) : booléen<br />

L’expression est vraie si le type directe <strong>de</strong> l’obj<strong>et</strong> <strong>et</strong> le type direct <strong>de</strong> « t » sont les<br />

mêmes ; sinon elle est fausse.<br />

oclIsKindOf<br />

Syntaxe : oclIsKindOf(t : oclType) : booléen<br />

L’expression est vraie si « t » est le type direct ou un <strong>de</strong>s super-types <strong>de</strong> l’obj<strong>et</strong>.<br />

Accès à une propriété redé<strong>fin</strong>ie dans un sous-type<br />

Si B est un sous-type <strong>de</strong> A <strong>et</strong> que tous les <strong>de</strong>ux disposent d’une propriété p1, il faut<br />

utiliser l’opération oclAsType pour accé<strong>de</strong>r à la propriété <strong>du</strong> type parent.<br />

context B inv :<br />

self.oclAsType(A).p1 >= 10 -- p1 <strong>de</strong> A<br />

self.p1 >= 100 -- p1 <strong>de</strong> B<br />

Extrémités d’association <strong>et</strong> navigation<br />

Il est possible <strong>de</strong> naviguer à travers une association en utilisant l’opérateur . suivi <strong>du</strong><br />

nom <strong>du</strong> rôle opposé.<br />

object.rolename<br />

C<strong>et</strong>te expression r<strong>et</strong>ourne l’ensemble <strong>de</strong>s obj<strong>et</strong>s correspondant à l’autre extrémité <strong>de</strong><br />

l’association. Dans le cas où la multiplicité maximale est <strong>de</strong> 1, l’expression r<strong>et</strong>ourne<br />

uniquement l’obj<strong>et</strong> associé.<br />

context Company<br />

inv : self.manager.isUnemployed = false -- 1 manager<br />

inv : self.employee->notEmpty() -- n employés<br />

Lorsque la navigation d’une association ne r<strong>et</strong>ourne qu’un seul obj<strong>et</strong>, celui-ci peut<br />

être manipulé comme un ensemble.<br />

22.06.2005 19/78


context Company inv :<br />

self.manager->size() = 1 -- 1 manager<br />

C<strong>et</strong>te caractéristique peut être intéressante si une extrémité d’association à 0..1<br />

comme multiplicité.<br />

context Person inv :<br />

self.wife->notEmpty() <br />

implies self.wife.sex = Sex::female<br />

Par défaut, la navigation r<strong>et</strong>ourne une collection <strong>de</strong> type S<strong>et</strong>. Si l’extrémité<br />

d’association est enrichie par la contrainte {or<strong>de</strong>red], la collection r<strong>et</strong>ournée est <strong>de</strong><br />

type Sequence.<br />

OCL dé<strong>fin</strong>it trois types <strong>de</strong> collection : S<strong>et</strong>, Sequence, Bag. Ces collections disposent<br />

toutes d’opérations prédé<strong>fin</strong>ies.<br />

Une propriété <strong>de</strong> collection peut-être accédée au moyen <strong>de</strong> l’opérateur -> suivi <strong>du</strong><br />

nom <strong>de</strong> la propriété.<br />

context Person inv :<br />

self.employer->size() < 3<br />

context Person inv :<br />

self.employer->isEmpty()<br />

Lorsque le nom d’un rôle n’est pas explicitement spécifié, il faut utiliser le nom <strong>du</strong><br />

type à l’extrémité <strong>de</strong> l’association mais en le commençant par une minuscule. Si<br />

c<strong>et</strong>te procé<strong>du</strong>re engendre une ambiguïté dans les noms <strong>de</strong>s propriétés, le nom <strong>du</strong><br />

rôle est obligatoirement requis (c’est le cas notamment <strong>de</strong>s associations réflexives).<br />

self.person -- Navigation vers la classe Person<br />

Pour exprimer une navigation vers une classe associative, il faut utiliser l’opérateur .<br />

suivi <strong>du</strong> nom <strong>de</strong> l’association en le commençant par une minuscule.<br />

self.job -- Navigation vers la classe associative Job<br />

Si l’association est réflexive, if faut encore donner le nom <strong>du</strong> rôle pour pouvoir<br />

naviguer vers la classe associative.<br />

-- Navigation vers la classe associative EmployeeRanking<br />

-- en utilisant le rôle bosses<br />

self.employeeRanking[bosses]->sum() = 0<br />

La navigation <strong>de</strong>puis une classe associative vers une <strong>de</strong>s classes <strong>de</strong> l’association est<br />

considéré comme une navigation normale. Cependant, en raison <strong>de</strong> la dé<strong>fin</strong>ition <strong>de</strong><br />

la classe associative dans UML, la navigation <strong>de</strong>puis une classe associative ne<br />

22.06.2005 20/78


<strong>et</strong>ourne toujours qu’un seul obj<strong>et</strong> par extrémité d’association. Celui-ci peut<br />

également être manipulé comme un ensemble.<br />

Collections<br />

OCL disposent comme nous venons <strong>de</strong> le voir trois sortes <strong>de</strong> collection (s<strong>et</strong>, bag,<br />

sequence) spécialisant la collection abstraite « collection ».<br />

Collection<br />

S<strong>et</strong> Bag Sequence<br />

Un s<strong>et</strong> représente un ensemble qui ne contient que <strong>de</strong>s valeurs uniques (ensemble<br />

au sens mathématique <strong>du</strong> terme). Le contenu d’un s<strong>et</strong> n’est pas ordonné.<br />

Un bag est un ensemble pouvant contenir plus d’une fois un élément. Le contenu<br />

d’un bag n’est pas ordonné.<br />

Une séquence est un ensemble pouvant contenir plus d’une fois un élément. Le<br />

contenu d’une séquence est ordonné.<br />

Il est possible d’initialiser le contenu d’une collection avec <strong>de</strong>s valeurs littérales.<br />

S<strong>et</strong> {} -- Ensemble vi<strong>de</strong><br />

S<strong>et</strong> {7, 9, 54, 90}<br />

S<strong>et</strong> {‘Pomme’, ‘Orange’, ‘Banane’}<br />

Lors <strong>de</strong> l’initialisation d’une séquence, il est possible <strong>de</strong> dé<strong>fin</strong>ir <strong>de</strong>s intervalles.<br />

Sequence {10, 20..24, 90} -- 10, 20, 21, 22, 23, 24, 90<br />

Conformité <strong>de</strong>s types « collection »<br />

Type Opérations<br />

S<strong>et</strong>(T) Collection(T)<br />

Sequence(T) Collection(T)<br />

Bag(T) Collection(T)<br />

Si « Vélo » <strong>et</strong> « Voiture » sont <strong>de</strong>s sous-types <strong>de</strong> « Véhicule » :<br />

• S<strong>et</strong>(Vélo) est conforme à S<strong>et</strong>(Véhicule)<br />

• S<strong>et</strong>(Vélo) est conforme à Collection(Vélo)<br />

• S<strong>et</strong>(Vélo) est conforme à Collection(Véhicule)<br />

22.06.2005 21/78


• S<strong>et</strong>(Vélo) n’est pas conforme à Bag(Vélo)<br />

• S<strong>et</strong>(Vélo) n’est pas conforme à Sequence(Vélo)<br />

Les <strong>de</strong>ux <strong>de</strong>rnière règles s’expliquent par le fait que S<strong>et</strong> <strong>et</strong> Sequence sont au même<br />

niveau dans la hiérarchie <strong>de</strong>s collections d’OCL.<br />

Opérations génériques sur les collections<br />

Les opérations sur les collections ne peuvent pas modifier le contenu d’une<br />

collection.<br />

L’opérateur -> perm<strong>et</strong> d’accé<strong>de</strong>r à une opération sur une collection.<br />

collection -> operation()<br />

« select » <strong>et</strong> « reject »<br />

select(exprBool) : Collection<br />

C<strong>et</strong>te fonction r<strong>et</strong>ourne une nouvelle collection restreinte aux éléments satisfaisant la<br />

condition. La nouvelle collection est une sous-collection <strong>de</strong> la collection <strong>de</strong> départ.<br />

Il existe trois syntaxes différentes pour exprimer la condition :<br />

select(exprBool)<br />

context Personne :: nbFilles() : entier<br />

post: result = self.enfants<br />

-> select(sexe = Sexe :: feminin) -> size<br />

select(iterateur | exprBool)<br />

context Personne :: nbFilles() : entier<br />

post: result = self.enfants<br />

-> select(fille | fille.sexe = Sexe :: feminin)<br />

-> size<br />

select(iterateur : type | exprBool)<br />

context Personne :: nbFilles() : entier<br />

post: result = self.enfants<br />

-> select(fille : Personne |<br />

fille.sexe = Sexe :: feminin) -> size<br />

L’utilisation d’une syntaxe sans itérateur explicite implique malgré tout un itérateur<br />

implicite anonyme.<br />

22.06.2005 22/78


Lorsqu’il y a une ambiguïté pour la sélection d’une propriété dans une expression, il<br />

faut obligatoirement utiliser une syntaxe avec itérateur.<br />

La contrainte ci-<strong>de</strong>ssous n’est pas vali<strong>de</strong> car l’accès à la propriété « lastName » est<br />

ambiguë.<br />

context Person<br />

inv: employer->forAll(employee->exists(lastName = name)<br />

En eff<strong>et</strong>, « lastName » peut dans c<strong>et</strong>te expression s’appliquer soit à l’instance <strong>de</strong><br />

personne qui a déclenché le contrôle <strong>de</strong> la contrainte ou aux instances <strong>de</strong> la<br />

collection r<strong>et</strong>ournée par la navigation d’ « employer » vers « employee ». Il faut donc<br />

spécifier explicitement à quelle instance s’applique la propriété.<br />

ou bien<br />

ou encore<br />

context Person<br />

inv: employer->forAll(employee->exists(p |<br />

p.lastName = name)<br />

context Person<br />

inv: employer->forAll(employee->exists(p : Person |<br />

p.lastName = name)<br />

context Person<br />

inv: employer->forAll(employee->exists(<br />

self.lastName = name)<br />

reject(exprBool) : Collection<br />

C<strong>et</strong>te fonction r<strong>et</strong>ourne une nouvelle collection restreinte aux éléments ne<br />

satisfaisant pas une condition. La nouvelle collection est une sous-collection <strong>de</strong> la<br />

collection <strong>de</strong> départ. Les trois formes <strong>de</strong> syntaxe sont possibles.<br />

« collect »<br />

collect(expr) : Bag<br />

C<strong>et</strong>te fonction r<strong>et</strong>ourne un bag construit à partir <strong>de</strong> la collection <strong>de</strong> départ mais<br />

contenant <strong>de</strong>s éléments <strong>du</strong> type <strong>de</strong> l’expression. La nouvelle collection n’a pas<br />

forcément le même type que la collection <strong>de</strong> départ. Le nombre d’éléments <strong>du</strong> bag<br />

est le même que celui <strong>de</strong> la collection <strong>de</strong> départ. Les trois formes <strong>de</strong> syntaxe sont<br />

possibles.<br />

self.employee->collect(birthDate)<br />

self.employee->collect(p | p.birthDate)<br />

self.employee->collect(p : Person | p.birthDate)<br />

22.06.2005 23/78


L’expression ci-<strong>de</strong>ssus r<strong>et</strong>ourne un bag contenant les dates <strong>de</strong> naissance <strong>de</strong> tous les<br />

employés <strong>de</strong> la société. La collection <strong>de</strong> départ est un s<strong>et</strong>(Employee) <strong>et</strong> la collection<br />

d’arrivée est un bag(Date).<br />

Il existe un raccourci pour utiliser la fonction « collect ». L’application d’une propriété<br />

à une collection est interprétée comme un appel implicite à « collect ».<br />

« forAll »<br />

self.employee.birthDate<br />

forAll(exprBool) : Boolean<br />

C<strong>et</strong>te fonction r<strong>et</strong>ourne vrai si la condition est vraie pour tous les éléments <strong>de</strong> la<br />

collection. Les trois formes <strong>de</strong> syntaxe sont possibles.<br />

« forAll » perm<strong>et</strong> également d’avoir plus d’un itérateur sur une même collection. Il<br />

s’agit en fait d’appliquer la fonction au pro<strong>du</strong>it cartésien <strong>de</strong> la collection avec ellemême.<br />

context Company inv<br />

self.employee->forAll(e1, e2 |<br />

e1 e2 implies e1.forename e2.forename<br />

context Company inv<br />

self.employee->forAll(e1, e2 : Person|<br />

e1 e2 implies e1.forename e2.forename<br />

Ces <strong>de</strong>ux contraintes sont i<strong>de</strong>ntiques. Elles perm<strong>et</strong>tent <strong>de</strong> s’assurer que tous les<br />

employés ont <strong>de</strong>s prénoms différents.<br />

forename<br />

A<br />

B<br />

C<br />

Pro<strong>du</strong>it cartésien<br />

e1.forename e2.forename e1 e2 implies e1.forename e2.forename<br />

A A VRAI<br />

A B VRAI<br />

A C VRAI<br />

B A VRAI<br />

B B VRAI<br />

B C VRAI<br />

C A VRAI<br />

C B VRAI<br />

C C VRAI<br />

On pourrait également écrire c<strong>et</strong>te contrainte <strong>de</strong> la façon suivante :<br />

22.06.2005 24/78


« exists »<br />

context Company inv<br />

self.employee->forAll(e1 |<br />

self.employee->forAll(e2 |<br />

e1 e2 implies e1.forename e2.forename))<br />

exists(exprBool) : Boolean<br />

C<strong>et</strong>te fonction r<strong>et</strong>ourne vrai si une condition est vraie pour au moins un élément <strong>de</strong> la<br />

collection, sinon elle r<strong>et</strong>ourne faux. Les trois formes <strong>de</strong> syntaxe sont possibles.<br />

« iterate »<br />

context Classe::ajouter(unEleve : Personne)<br />

pre : classeNonSurchargee : nb_eleves exists(unEleve)<br />

context Classe::effectif()<br />

post: result = nb_eleves<br />

iterate(iterateur : T ; accumulateur : T = expr1 |expr2) : ???<br />

C<strong>et</strong>te fonction perm<strong>et</strong> d’itérer sur une collection.<br />

Les opérations « reject », « select », « forAll », « exists » <strong>et</strong> « collect » peuvent se<br />

faire au moyen <strong>de</strong> la fonction iterate.<br />

« expr1 » représente la valeur initiale <strong>de</strong> la variable « accumulateur ».<br />

context Personne :: revenusDesParents() : Integer<br />

post: result = self.parent<br />

->iterate(p : Personne;<br />

val : Integer = 0 |<br />

val = p.revenus->sum())<br />

La métho<strong>de</strong> « revenusDesParents » doit r<strong>et</strong>ourner un entier correspondant à la<br />

somme <strong>de</strong>s revenus <strong>de</strong> chaque parent.<br />

collection->collect(x: T | x.property)<br />

correspond aussi à<br />

collection->iterate(x: T; acc : T2 = Bag{} | x.property)<br />

« isEmpty » <strong>et</strong> « notEmpty »<br />

isEmpty() : Boolean<br />

C<strong>et</strong>te fonction r<strong>et</strong>ourne vrai si la collection est vi<strong>de</strong>, faux sinon.<br />

22.06.2005 25/78


notEmpty() : Boolean<br />

C<strong>et</strong>te fonction r<strong>et</strong>ourne vrai si la collection n’est pas vi<strong>de</strong>, faux sinon.<br />

« size »<br />

size() : Integer<br />

C<strong>et</strong>te fonction r<strong>et</strong>ourne la cardinalité d’une collection (le nombre d’éléments contenus<br />

par la collection).<br />

« count »<br />

count(unObj<strong>et</strong>) : Integer<br />

C<strong>et</strong>te fonction r<strong>et</strong>ourne le nombre <strong>de</strong> fois qu’unObj<strong>et</strong> figure dans la collection (pour<br />

un s<strong>et</strong> ce sera toujours 1).<br />

« sum »<br />

sum() : T<br />

C<strong>et</strong>te fonction r<strong>et</strong>ourne la valeur <strong>de</strong> l’addition <strong>de</strong> tous les éléments (<strong>de</strong> type T) <strong>de</strong> la<br />

collection. Les élément <strong>de</strong> la collection doivent évi<strong>de</strong>mment supporter l’opération +<br />

(c’est le cas <strong>de</strong>s types Integer <strong>et</strong> Real). Le type <strong>de</strong> r<strong>et</strong>our <strong>de</strong> la fonction dépend <strong>du</strong><br />

contenu <strong>de</strong> la collection.<br />

« inclu<strong>de</strong>s » , « inclu<strong>de</strong>sAll », « exclu<strong>de</strong> » <strong>et</strong> « exclu<strong>de</strong>All »<br />

inclu<strong>de</strong>s(unObj<strong>et</strong>) : Boolean<br />

R<strong>et</strong>ourne vrai si unObj<strong>et</strong> fait partie <strong>de</strong> la collection, sinon faux<br />

exclu<strong>de</strong>s(unObj<strong>et</strong>) : Boolean<br />

R<strong>et</strong>ourne vrai si unObj<strong>et</strong> ne fait pas partie <strong>de</strong> la collection, sinon faux.<br />

inclu<strong>de</strong>sAll(uneCollection)<br />

R<strong>et</strong>ourne vrai si les elements <strong>de</strong> uneCollection sont tous contenus dans la collection,<br />

sinon faux.<br />

exclu<strong>de</strong>sAll(uneCollection)<br />

R<strong>et</strong>ourne vrai si aucun <strong>de</strong>s elements <strong>de</strong> uneCollection n’est contenu dans la<br />

collection, sinon faux.<br />

isUnique(expr) : Boolean<br />

22.06.2005 26/78


R<strong>et</strong>ourne vrai si l’expression r<strong>et</strong>ourne une valeur unique pour chaque élément <strong>de</strong> la<br />

collection, sinon faux.<br />

sortedBy(expr) : Sequence<br />

C<strong>et</strong>te fonction r<strong>et</strong>ourne une séquence ordonnée d’après l’expression passée en<br />

paramètre. Le plus p<strong>et</strong>it élément pour l’expression <strong>de</strong>vient le premier élément <strong>de</strong> la<br />

séquence. Le type <strong>de</strong>s éléments <strong>de</strong> la collection source doit implémenter l’opération<br />

Sequence asSequence()<br />

S<strong>et</strong> –>Bag asBag()<br />

Bag –> Sequence asSequence())<br />

Bag –> S<strong>et</strong> asS<strong>et</strong>()<br />

self.employee->collect(birthDate)->asS<strong>et</strong>()<br />

Opérations propres à chaque type <strong>de</strong> collection<br />

S<strong>et</strong><br />

=(unS<strong>et</strong> : S<strong>et</strong>) : Boolean<br />

C<strong>et</strong>te fonction r<strong>et</strong>ourne vrai si les <strong>de</strong>ux s<strong>et</strong>s possè<strong>de</strong>nt les mêmes éléments, faux<br />

sinon.<br />

-(unS<strong>et</strong> : S<strong>et</strong>) : S<strong>et</strong><br />

C<strong>et</strong>te fonction r<strong>et</strong>ourne un nouveau s<strong>et</strong> contenant les éléments <strong>du</strong> s<strong>et</strong> qui ne se<br />

trouvent pas dans unS<strong>et</strong>.<br />

union(unS<strong>et</strong> : S<strong>et</strong>) : S<strong>et</strong><br />

union(unBag : Bag) : Bag<br />

22.06.2005 27/78


intersection(unS<strong>et</strong> : S<strong>et</strong>) : S<strong>et</strong><br />

intersection(unBag : Bag) : Bag<br />

including(unObj<strong>et</strong> : T) : S<strong>et</strong><br />

C<strong>et</strong>te fonction r<strong>et</strong>ourne un ensemble contenant les éléments <strong>de</strong> l’ensemble plus<br />

unObj<strong>et</strong>.<br />

excluding(unObj<strong>et</strong> : T): S<strong>et</strong><br />

C<strong>et</strong>te fonction r<strong>et</strong>ourne un ensemble contenant les éléments <strong>de</strong> l’ensemble à<br />

l’exception <strong>de</strong> unObj<strong>et</strong>.<br />

symm<strong>et</strong>ricDifference(unS<strong>et</strong> : S<strong>et</strong>) : S<strong>et</strong><br />

C<strong>et</strong>te fonction r<strong>et</strong>ourne les éléments qui sont soit dans le s<strong>et</strong>, soit dans unS<strong>et</strong> mais<br />

pas dans les <strong>de</strong>ux à la fois.<br />

Bag<br />

=(unBag : Bag) : Boolean<br />

C<strong>et</strong>te fonction r<strong>et</strong>ourne vrai si les <strong>de</strong>ux bags possè<strong>de</strong>nt les mêmes éléments, le<br />

même nombre <strong>de</strong> fois.<br />

union(unBag : Bag) : Bag<br />

union(unS<strong>et</strong> : S<strong>et</strong>) : Bag<br />

intersection (unBag : Bag) : Bag<br />

intersection (unS<strong>et</strong> : S<strong>et</strong>) : Bag<br />

including(unObj<strong>et</strong> : T) : Bag<br />

excluding(unObj<strong>et</strong> : T): Bag<br />

C<strong>et</strong>te fonction r<strong>et</strong>ourne un bag contenant les éléments <strong>du</strong> bag d’origine à l’exception<br />

<strong>de</strong> toutes les occurrences d’unObj<strong>et</strong>.<br />

Sequence<br />

=(uneSequence : Sequence) : Boolean<br />

C<strong>et</strong>te fonction r<strong>et</strong>ourne vrai si les <strong>de</strong>ux séquences possè<strong>de</strong>nt les mêmes éléments<br />

dans le même ordre.<br />

union(uneSequence : Sequence) : Sequence<br />

append(unObj<strong>et</strong> : T) : Sequence<br />

C<strong>et</strong>te fonction r<strong>et</strong>ourne une nouvelle séquence contenant les éléments <strong>de</strong> la<br />

séquence d’origine suivi <strong>de</strong> unObj<strong>et</strong>.<br />

22.06.2005 28/78


prepend(unObj<strong>et</strong> : T) : Sequence<br />

C<strong>et</strong>te fonction r<strong>et</strong>ourne une nouvelle séquence commençant par unObj<strong>et</strong> suivi par<br />

les éléments <strong>de</strong> la séquence d’origine.<br />

including(unObj<strong>et</strong> : T) : Sequence<br />

excluding(unObj<strong>et</strong> : T): Sequence<br />

subSequence(<strong>de</strong>but : Integer, <strong>fin</strong> Integer) : Sequence<br />

C<strong>et</strong>te fonction r<strong>et</strong>ourne une nouvelle séquence contenant les éléments contenus<br />

entre les <strong>de</strong>ux bornes.<br />

at(indice : Integer) : T<br />

C<strong>et</strong>te fonction r<strong>et</strong>ourne l’instance se trouvant à l’indice indiqué dans la séquence.<br />

first() : T<br />

last() : T<br />

Ces fonctions r<strong>et</strong>ourne la première <strong>et</strong> la <strong>de</strong>rnière instance <strong>de</strong> la séquence.<br />

Remarques<br />

Il ne sert à rien <strong>de</strong> spécifier avec OCL ce qui est déjà exprimé par le modèle UML<br />

Contenu Conteneur<br />

0..*<br />

1<br />

context Contenu inv:<br />

self.conteneur -> size = 1<br />

Bibliographie<br />

Modélisation obj<strong>et</strong> avec UML, <strong>de</strong>uxième édition, Pierre-Alain Müller <strong>et</strong> Nathalie<br />

Gaertner, Eyrolles, Paris, 2000, ISBN 2-212-09122-2<br />

OMG – Unified Mo<strong>de</strong>ling Language Specification, version 1.5, OMG, Mars 2003,<br />

http://www.omg.org/technology/documents/formal/uml.htm<br />

XMI<br />

1.12. Intro<strong>du</strong>ction<br />

22.06.2005 29/78


XMI (XML M<strong>et</strong>adata Interchange) est un langage <strong>de</strong> spécification <strong>de</strong>stiné à faciliter<br />

l’échange <strong>de</strong>s méta-données entre les outils <strong>de</strong> modélisation basés sur UML <strong>et</strong> les référentiels<br />

<strong>de</strong> méta-données basés eux sur le MOF (M<strong>et</strong>a Object Facilty) dans <strong>de</strong>s environnements<br />

hétérogènes.<br />

Il existe actuellement <strong>de</strong>ux versions <strong>de</strong> XMI. La version 1.3 (01 mai 2003) dé<strong>fin</strong>it comment<br />

utiliser <strong>de</strong>s XML Schémas au lieu <strong>de</strong> la traditionnelle DTD mais les fonctionalités sont<br />

i<strong>de</strong>ntiques à la version 1.2. La version 2.0 (02 mai 2003) apporte, elle, <strong>de</strong> nouveau éléments<br />

au langage XMI.<br />

Dans le cadre <strong>de</strong> ce proj<strong>et</strong>, nous nous sommes intéressés à la version 1.2 uniquement car notre<br />

outil <strong>de</strong> modélisation Poseidon for UML supportait uniquement c<strong>et</strong>te <strong>de</strong>rnière.<br />

Comme nous allons le voir, XMI est capable d’embarquer plus <strong>de</strong> sémantique qu’un modèle<br />

Java <strong>et</strong> supporte également les contraintes dé<strong>fin</strong>ies avec OCL.<br />

UML perm<strong>et</strong> <strong>de</strong> décrire <strong>de</strong>s modèles <strong>de</strong> façon orientée obj<strong>et</strong> alors que MOF dé<strong>fin</strong>it un<br />

framework pour la modélisation <strong>de</strong>s méta-données <strong>et</strong> fournit <strong>de</strong>s outils pour accé<strong>de</strong>r à ces<br />

méta-données à partir d’un langage <strong>de</strong> programmation. XMI perm<strong>et</strong> d’échanger <strong>de</strong>s métadonnées<br />

sous la forme <strong>de</strong> flux ou <strong>de</strong> fichiers en recourant à XML.<br />

1.13. Classes <strong>et</strong> types <strong>de</strong> données<br />

A partir <strong>du</strong> modèle UML ci-<strong>de</strong>ssus, voilà à quoi ressemble un fichier XMI. Nous allons<br />

commencer par étudier comment sont dé<strong>fin</strong>is les types int <strong>et</strong> String. Les balises importantes<br />

sont mise en évi<strong>de</strong>nce grâce au surlignage.<br />

Voici le contenu intégral <strong>du</strong> fichier XMI généré par Poseidon for UML:<br />

<br />

<br />

<br />

<br />

N<strong>et</strong>beans XMI Writer<br />

1.0<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

22.06.2005 30/78


<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

22.06.2005 31/78


<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

Les types <strong>de</strong> données se trouve (avec Poseidon For UML) dans un paqu<strong>et</strong>age java.lang. Les<br />

types élémentaires sont décrits au moyen <strong>de</strong> la balise alors que les types<br />

composés le sont avec . Il est intéressant <strong>de</strong> remarquer pour ces <strong>de</strong>ux éléments<br />

22.06.2005 32/78


l’attribut xmi.id dont la valeur perm<strong>et</strong>tra <strong>de</strong> faire référence au type en question à partir d’une<br />

autre balise <strong>du</strong> fichier.<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />


<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />


dataValue = '-99-26--92-79-247d4a:f5d0b19c<strong>de</strong>:-7ffd'><br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

Nous r<strong>et</strong>rouvons bien notre classe « client » dé<strong>fin</strong>ie par une balise . C<strong>et</strong>te<br />

<strong>de</strong>rnière contient les attributs grâce à . Pour le type <strong>de</strong>s attributs, nous<br />

trouvons un lien dans vers les types que nous avons présentés ci<strong>de</strong>ssus<br />

au moyen <strong>de</strong> l’attribut xmi.idref. <strong>de</strong> ou <strong>de</strong> .<br />

<br />

<br />

<br />

<br />

<br />


<br />

<br />

<br />

<br />

<br />

<br />

<br />

Il est possible <strong>de</strong> dé<strong>fin</strong>ir une valeur par défaut pour un attribut.<br />

<br />

<br />

<br />

<br />

1.14. Associations<br />

En se basant sur le modèle UML ci-<strong>de</strong>ssus, nous allons maintenant étudier comment une<br />

association 1-1 est décrite en XMI.<br />

Voici un aperçu <strong>du</strong> fichier XMI généré par Poseidon for UML:<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

22.06.2005 37/78


<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

Les balises principales pour décrire une association sont repro<strong>du</strong>ites ci-<strong>de</strong>ssous.<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

22.06.2005 38/78


<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

Attribut Description<br />

visibility spécifie la visibilité <strong>de</strong> l’extrémité d’association (public, protected,<br />

private, package)<br />

isSpecification spécifie si l’extrémité d’association fait partie <strong>de</strong> la spécification<br />

(true) ou <strong>de</strong> la réalisation (false) <strong>de</strong> la classe<br />

iNavigable spécifie si l’extrémité d’association peut être traversée <strong>de</strong>puis<br />

l’instance associée (true) ou non (false)<br />

o<strong>de</strong>ring spécifie si les éléments résultant <strong>de</strong> la traversée <strong>de</strong> c<strong>et</strong>te extrémité<br />

d’association sont ordonnés (or<strong>de</strong>red) ou non(unor<strong>de</strong>red)<br />

aggregation spécifie si la classe associée à c<strong>et</strong>te extrémité d’association est un<br />

agrégat (aggregate) ou un composé (composite) ou encore une<br />

classe normale (none)<br />

targ<strong>et</strong>Scope spécifie si l’extrémité d’association est associé à une instance ou à<br />

une classe<br />

changeability spécifie si l’instance associée à c<strong>et</strong>te extrémité d’association peut<br />

être changée (changeable) ou s’il est ne peut pas être changée<br />

(frozen) ou s’il est uniquement possible d’ajouter <strong>de</strong> nouvelles<br />

instances (addOnly)<br />

<br />

Attribut Description<br />

lower spécifie le nombre minimum d’instance pouvant être associé à<br />

l’extrémité d’association<br />

upper spécifie le nombre maximum d’instance pouvant être associé à<br />

22.06.2005 39/78


l’extrémité d’association<br />

La seule chose qui change pour une association 1-n par rapport à une association 1-1 c’est la<br />

valeur <strong>de</strong> la borne maximale <strong>de</strong> la multiplicité.<br />

<br />

Si l’attribut « upper » <strong>de</strong> la balise a la valeur –1, il s’agit d’une<br />

association « à plusieurs ».<br />

Une association n-n voit donc ses <strong>de</strong>ux extrémités d’association prendre la valeur –1 comme<br />

multiplicité maximale.<br />

1.15. Relations <strong>de</strong> généralisation<br />

Voici un aperçu <strong>du</strong> fichier XMI généré par Poseidon for UML:<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

22.06.2005 40/78


<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

…<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

Si une classe B spécialise une classe A, alors la classe B contient une balise<br />

qui fait référence à une autre balise<br />

dans le fichier.<br />

La balise perm<strong>et</strong> <strong>de</strong> savoir quelle est la classe parent<br />

() <strong>et</strong> la classe enfant ()<strong>de</strong> la<br />

relation <strong>de</strong> généralisation.<br />

1.16. Classes associatives<br />

22.06.2005 41/78


collabore<br />

Employe Mandat<br />

0..*<br />

0..*<br />

Collaboration<br />

nbHeures<br />

Poseidon for UML ne supportant pas les classes associatives, nous avons utilisé Rational Rose<br />

<strong>et</strong> son add-in JCRUML pour obtenir un fichier XMI contenant une classe associative.<br />

Voici un aperçu <strong>du</strong> fichier XMI généré par Poseidon for UML:<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

22.06.2005 42/78


<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

Une classe associative porte bien son nom puisqu’elle dispose à la fois <strong>de</strong>s caractéristiques<br />

d’une classe () <strong>et</strong> <strong>de</strong> celles d’une association<br />

().<br />

<br />

<br />

<br />

…<br />

<br />

<br />

…<br />

<br />

<br />

<br />

<br />

…<br />

<br />

<br />

<br />

1.17. Contraintes OCL<br />

XMI est capable d’embarquer <strong>de</strong>s contraintes OCL. Nous allons voir comment la contrainte<br />

ci-<strong>de</strong>ssous est déclarée dans le fichier XMI.<br />

context Article inv :<br />

prix > 0.0<br />

Voici un aperçu <strong>du</strong> fichier XMI généré par Poseidon for UML:<br />

<br />

<br />

<br />

<br />

…<br />

22.06.2005 43/78


…<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

L’existence d’une contrainte OCL sur une classe est déclarée au moyen <strong>de</strong> la balise<br />

. C<strong>et</strong>te <strong>de</strong>rnière référence une balise <br />

qui contient l’expression OCL dé<strong>fin</strong>issant la contrainte dans l’attribut « body » <strong>de</strong> la balise<br />

.<br />

1.18. Bibliographie<br />

OMG – XML M<strong>et</strong>adata Interchange Specification, version 1.2, OMG, Janvier 2002,<br />

http://www.omg.org/technology/documents/formal/xmi.htm<br />

OMG – Unifield Mo<strong>de</strong>ling Language Specification, version 1.5, OMG, Mars 2003,<br />

http://www.omg.org/technology/documents/format/xmi.htm<br />

1.19. Oracle 9i<br />

L’objectif est <strong>de</strong> décrire ici globalement les capacités relationnelles obj<strong>et</strong>s supportée par<br />

Oracle, soit :<br />

22.06.2005 44/78


• Les types dé<strong>fin</strong>is par l'utilisateur, qui sont les classes <strong>de</strong> la base <strong>de</strong> données.<br />

• Les références d'obj<strong>et</strong>s (semblables aux pointeurs).<br />

• Les obj<strong>et</strong>s <strong>de</strong> gran<strong>de</strong> taille ou Large Objects (LOB) <strong>et</strong> leurs dérivés.<br />

• L’héritage<br />

• Les procé<strong>du</strong>res stockées en langage PL/SQL2 <strong>et</strong>/ou Java (JDBC3 <strong>et</strong> SQLJ4).<br />

Dans le cadre particulier <strong>de</strong> ce <strong>de</strong> ce proj<strong>et</strong>, les fonctionnalités <strong>de</strong>s métho<strong>de</strong>s <strong>de</strong>s classes<br />

persistantes ont été volontairement mises <strong>de</strong> coté, c’est pourquoi nous n’allons que très<br />

peu les développer ici.<br />

1.19.1. Référence<br />

Le modèle <strong>de</strong> référence utilisé par Oracle est le manifeste5 <strong>de</strong> Date <strong>et</strong> Darwen. C<strong>et</strong>te<br />

approche basé sur la <strong>du</strong>alité <strong>de</strong> structure est aussi cohérent avec la double vision <strong>de</strong><br />

l’obj<strong>et</strong> BD : « encapsulation » associée aux domaines, « structuration » associée aux<br />

relations. Dans ce manifeste les <strong>de</strong>ux nouveautés essentielles naturellement intégrées<br />

dans le modèle relationnel <strong>de</strong> bases sont :<br />

• Les types <strong>de</strong> données extensibles<br />

• L’héritage<br />

1.19.2. Description <strong>de</strong>s fonctionnalités obj<strong>et</strong> Oracle<br />

1.19.2.1. Types 6<br />

Oracle dé<strong>fin</strong>it <strong>de</strong> nouveaux types <strong>de</strong> données pouvant être créés par les utilisateurs <strong>et</strong><br />

qui peuvent être utilisés pour modéliser <strong>de</strong>s obj<strong>et</strong>s. Ces obj<strong>et</strong>s sont semblables aux<br />

mécanismes <strong>de</strong> classes que l'on trouve en Java, ils peuvent contenir:<br />

• Des attributs qui peuvent être:<br />

Des types scalaires dé<strong>fin</strong>is par Oracle (VARCHAR, NUMBER, DATE, …).<br />

Des références sur d'autres obj<strong>et</strong>s (pointeurs).<br />

Des obj<strong>et</strong>s.<br />

Des collections d'obj<strong>et</strong>s.<br />

Des obj<strong>et</strong>s larges non structurés (LOBs, BLOBs CLOBs, …).<br />

• Des métho<strong>de</strong>s, dont<br />

Des métho<strong>de</strong>s membres (MEMBER) qui s'applique à un obj<strong>et</strong><br />

Des métho<strong>de</strong>s statiques (STATICS) qui s'applique à la classe<br />

Ces nouveaux types peuvent être interrogés par les moyens habituels, c'est-à-dire<br />

requêtes SQL, PL/SQL ou autres. Ils peuvent être inclus dans <strong>de</strong>s tables <strong>de</strong> plusieurs<br />

manières:<br />

• Comme une colonne <strong>de</strong> table.<br />

• Comme un tuple (une ligne est un obj<strong>et</strong>).<br />

2 PL/SQL est une extension procé<strong>du</strong>rale à la norme SQL. C’est le langage propriétaire d’Oracle<br />

3 JavaDataBaseConnectivity : APIs Java <strong>de</strong> connexion pour une base <strong>de</strong> données cible<br />

4 SQLJ précompilateur Java pour SQL. Génère <strong>de</strong>s appels JDBC<br />

5 Est également nommé troisième manifeste<br />

6 Ce qu' Oracle dénomme un type est en fait ce qu'on appelle dans la terminologie obj<strong>et</strong> une classe.<br />

22.06.2005 45/78


Quand les obj<strong>et</strong>s sont dé<strong>fin</strong>is comme lignes (tuples), un i<strong>de</strong>ntificateur unique, appelé OID<br />

(Object I<strong>de</strong>ntifier), leur est automatiquement assigné. C<strong>et</strong> i<strong>de</strong>ntificateur est unique pour<br />

chaque obj<strong>et</strong> <strong>de</strong> la base <strong>de</strong> données <strong>et</strong> il n'est jamais réutilisé, même si l'obj<strong>et</strong> est<br />

détruit.<br />

Les fonctions membres <strong>de</strong>s types peuvent être écrites <strong>de</strong> différentes façons :<br />

• En PL / SQL, <strong>de</strong> la même manière que l’on écrit un trigger ou une procé<strong>du</strong>re stockée.<br />

• En Java (à partir <strong>de</strong> la version 8i)<br />

• Dans un langage externe à la base <strong>de</strong> données comme le C ou le C++.<br />

1.19.2.2. OID <strong>et</strong> Références<br />

L’implémentation <strong>de</strong> données obj<strong>et</strong>s persistantes nécessitent la notion d'i<strong>de</strong>ntificateur<br />

d’obj<strong>et</strong>. Oracle intro<strong>du</strong>it le concept <strong>de</strong> références dans la base <strong>de</strong> données. Les<br />

références sont semblables aux références que l'on trouve dans les langages <strong>de</strong><br />

programmation orientés obj<strong>et</strong> comme le C++ ou Java. Elles peuvent être vues comme<br />

une extension <strong>de</strong> la notion <strong>de</strong> clé étrangère, <strong>et</strong> elles représentent le principal moyen pour<br />

représenter l'intégrité référentielle dans les données obj<strong>et</strong> comme les types dé<strong>fin</strong>is par<br />

l'utilisateur.<br />

Une référence est dé<strong>fin</strong>ie par l'utilisation <strong>du</strong> mot clé REF <strong>et</strong>, en interne, elle utilise l'OID<br />

(object I<strong>de</strong>ntifier) pour dé<strong>fin</strong>ir sa cible. L'obtention <strong>de</strong> la référence sur un obj<strong>et</strong> se fait en<br />

appelant la fonction REF(…), <strong>et</strong> le déréférencement se fait <strong>de</strong> la même manière par la<br />

fonction DEREF(…).<br />

L'utilisateur peut utiliser les références comme si il manipulait l'obj<strong>et</strong> qui est référencé,<br />

sans restrictions.<br />

1.19.2.3. Collections d'obj<strong>et</strong>s<br />

Oracle perm<strong>et</strong> <strong>de</strong> gérer les données qui ne respectent pas la première forme normale <strong>de</strong><br />

Boyce-Codd, 7 comme :<br />

• Les tables en tant qu’attributs <strong>de</strong> tables (Nested Tables)<br />

• Les tableaux <strong>de</strong> taille variable (Varrays)<br />

Les attributs <strong>de</strong>s obj<strong>et</strong>s ainsi que les colonnes <strong>de</strong>s tables peuvent être d’un <strong>de</strong> ces types,<br />

<strong>et</strong> ainsi, les développeurs ont la possibilité <strong>de</strong> modéliser <strong>de</strong>s relations un à plusieurs (1 –<br />

n) <strong>et</strong> plusieurs à plusieurs (n – m) directement à l’intérieur <strong>de</strong>s obj<strong>et</strong>s <strong>de</strong> leur schéma.<br />

• Nested tables<br />

Une nested table est une table à l'intérieur d'une autre table, elle est particulièrement<br />

utilisée dans la modélisation <strong>de</strong>s relations 1-n <strong>et</strong> <strong>de</strong>s liens i<strong>de</strong>ntifiants. Une table<br />

imbriquée possè<strong>de</strong> toutes les caractéristiques d'une table normale.<br />

• Varrays<br />

Un VARRAY contient zéro ou plusieurs éléments <strong>du</strong> même type, ayant une position<br />

unique sous la forme d'une collection triée. Le VARRAY est utilisé comme une seule entité<br />

par SQL, il a <strong>de</strong>ux attributs:<br />

7 Souvent appelé NF 2 (Not First Normal Form)<br />

22.06.2005 46/78


Count: Nombre actuel d'éléments.<br />

Limit: Nombre maximal d'éléments.<br />

Les valeurs sont stockées dans une seule ligne physique si elles ne dépassent pas 4 kb.<br />

Les positions <strong>de</strong>s éléments sont indiquées par <strong>de</strong>s entiers <strong>et</strong> commencent à 1. Il n'est<br />

pas possible <strong>de</strong> dé<strong>fin</strong>ir <strong>de</strong>s valeurs par défaut ou <strong>de</strong>s contraintes sur un VARRAY ou ses<br />

éléments.<br />

• Différences entre VARRAY <strong>et</strong> NESTED TABLE<br />

VARRAY NESTED TABLE<br />

Collection triée Comportement multi-ensemble<br />

Stocké dans le segment Stocké hors <strong>du</strong> segment<br />

Ne supporte pas les in<strong>de</strong>x Supporte les in<strong>de</strong>x<br />

Limite sur le nombre d'éléments Pas <strong>de</strong> limite sur la taille<br />

Pas <strong>de</strong> SELECT sur les éléments SELECT possible sur les lignes d'une<br />

NESTED TABLE<br />

On utilisera donc vraisemblablement un VARRAY pour <strong>de</strong>s p<strong>et</strong>ites quantités <strong>de</strong> données<br />

<strong>de</strong> taille connue <strong>et</strong> une nested table quand les données sont moins uniformes <strong>et</strong> moins<br />

prévisibles.<br />

1.19.2.4. Métho<strong>de</strong>s<br />

• Métho<strong>de</strong>s membres<br />

Chaque type peut comporter <strong>de</strong>s métho<strong>de</strong>s. Ces métho<strong>de</strong>s peuvent être implémentée<br />

avec <strong>de</strong>s fonctions (elles r<strong>et</strong>ournent une valeur) ou une procé<strong>du</strong>re. La directive SELF<br />

désigne l'obj<strong>et</strong> sur lequel porte la métho<strong>de</strong>.<br />

• Métho<strong>de</strong>s statique<br />

La métho<strong>de</strong> n’est pas rattaché à un obj<strong>et</strong> particulier mais à la classe complète.<br />

Une métho<strong>de</strong> memebre ou statique peut être utilisée<br />

• Appelée dans un programme PL/SQL.<br />

• Evaluée8, dans une requête SQL si elle r<strong>et</strong>ourne une valeur (fonction).<br />

Les fonctionnalités <strong>du</strong> SGBD pour l’implémentation <strong>de</strong>s métho<strong>de</strong>s ne sont que très peu<br />

développées ici, le cahier <strong>de</strong>s charges <strong>du</strong> proj<strong>et</strong> spécifiant clairement que nous<br />

n’implémenterons pas <strong>de</strong> métho<strong>de</strong>s au niveau <strong>de</strong>s obj<strong>et</strong>s persistants<br />

1.19.2.5. LOBS<br />

Les LOBs sont <strong>de</strong>s obj<strong>et</strong>s <strong>de</strong> gran<strong>de</strong> taille (en anglais Large Objects). Ils se divisent en<br />

<strong>de</strong>ux catégories, <strong>et</strong> supportent plusieurs types:<br />

• Internes<br />

BLOBs : Binary Large Objects (Ex: Images, sons, vidéo)<br />

CLOBs : Character Large Objects (Ex: Textes encodage single byte)<br />

NCLOBs : National Character Large Objects (Ex: Textes encodage multi-byte)<br />

8 La fonction qui implémente la fonction membre doit impérativement être pure<br />

22.06.2005 47/78


• Externes<br />

BFILEs : Pointeur sur <strong>de</strong>s fichiers stockés à même le système d'exploitation.<br />

L'obj<strong>et</strong> DIRECTORY est utilisé pour manipuler <strong>de</strong>s LOBs externes (BFILE), il représente un<br />

alias sur un répertoire <strong>du</strong> système d'exploitation.<br />

Les <strong>de</strong>ux types <strong>de</strong> LOB ont <strong>de</strong>s fonctionnalités pour <strong>de</strong>s utilisations différentes.<br />

LOBs Internes LOBs externes<br />

Stockés dans la base <strong>de</strong> données. Stockés à l'extérieur <strong>de</strong> la base <strong>de</strong> données, en<br />

tant que fichiers. La base ne gar<strong>de</strong> qu'une<br />

référence sur le fichier.<br />

Intégrés au modèle transactionnel (ACID). Aucune gestion <strong>de</strong>s transactions.<br />

Complètement intégrés à la base <strong>de</strong> données. Utilisables en lecture seule uniquement.<br />

(ajout, modif., suppression)<br />

Peu fortement augmenter la taille <strong>de</strong> la base Augmentation <strong>de</strong> taille négligeable<br />

<strong>de</strong> données<br />

Peuvent implémenter plusieurs formats N'implémente que le format (BFILE)<br />

(CLOBS / BLOBS / NCLOBS)<br />

1.19.2.6. Héritage<br />

L'héritage9 est une technique utilisée dans le développement orienté obj<strong>et</strong> a<strong>fin</strong> <strong>de</strong> créer<br />

<strong>de</strong>s classes qui contiennent <strong>de</strong>s attributs <strong>et</strong> <strong>de</strong>s métho<strong>de</strong>s généralisées pour les obj<strong>et</strong>s<br />

qui en dépen<strong>de</strong>nt. Les classes les plus générales sont appelées super-type <strong>et</strong> celles qui<br />

en dépen<strong>de</strong>nt sous-type.<br />

Exemple:<br />

Un sous-type peut hériter directement d’un super-type ou indirectement au travers <strong>de</strong> la<br />

hiérarchie <strong>de</strong>s types. Un sous-type ne peut hériter que d’un seul super-type, l’héritage<br />

multiple n’est pas supporté. Les attributs <strong>du</strong> super-type sont hérités dans tous les soustypes.<br />

Les droits sur les attributs private ou protected n’existent pas, ils sont tous public..<br />

La spécialisation <strong>de</strong>s sous-types s’effectue selon les règles <strong>de</strong> la programmation obj<strong>et</strong>,<br />

soit création <strong>de</strong> nouveaux attributs dans les sous-types, toutes les modifications<br />

effectuées sur les super-types sont répercutées dans leurs sous-types.<br />

La création d’un sous-type est l’action d’hériter d’un type qui s’appellera super-type,<br />

c<strong>et</strong>te opération s’effectue par la clause « UNDER ».<br />

• Propriétés <strong>de</strong>s types<br />

PERSONNES<br />

PHYSIQUES MORALES<br />

9 Oracle supporte la notion d’héritage <strong>de</strong>puis sa version 9.<br />

22.06.2005 48/78


Un type dé<strong>fin</strong>i comme « FINAL » (valeur par défaut) ne pourra pas être hérité par un<br />

sous-type. Un type « NOT FINAL » peut être transformé en « FINAL » uniquement s’il n’a<br />

pas <strong>de</strong> sous-type.<br />

La notion d’abstraction ou non, sous Oracle est dé<strong>fin</strong>ie par les clauses « NOT<br />

INSTANTIABLE » ou « INSTANTIABLE » ce qui va perm<strong>et</strong>tre aux développeurs <strong>de</strong> créer<br />

<strong>de</strong>s types abstraits. Un type « NOT INSTANTIABLE » est donc une classe abstraite, son<br />

instantiation est impossible.<br />

Par défaut un type est « INSTANTIABLE ».Un type « INSTANTIABLE » peut <strong>de</strong>venir<br />

«NOT INSTANTIABLE » <strong>et</strong> vice-versa.<br />

1.19.2.7. Principe <strong>de</strong> substitution <strong>et</strong> polymorphisme<br />

Le principe <strong>de</strong> substitution affirme qu’il doit être possible <strong>de</strong> substituer n’importe quel<br />

obj<strong>et</strong> instance d’un sous-type à n’importe quel obj<strong>et</strong> instance d’un super-type sans que la<br />

sémantique <strong>du</strong> programme écrit dans les termes <strong>du</strong> super-type ne soit affectée.<br />

Ceci est applicable pour tous les containers <strong>de</strong> type Oracle obj<strong>et</strong>s (ex : une variable, un<br />

attribut table ou vue). Sans le respect <strong>de</strong> ce principe, le polymorphisme ne peut être mis<br />

en œuvre.<br />

Le polymorphisme désigne un concept <strong>de</strong> la théorie <strong>de</strong>s types (types obj<strong>et</strong>s, REF ou<br />

collection d’obj<strong>et</strong>s), selon lequel un nom d’obj<strong>et</strong> peut désigner <strong>de</strong>s instances <strong>de</strong> types<br />

différents, issues d’une même arborescence. La clause «NOT SUBSTITUTABLE AT ALL<br />

LEVELS » désactive le principe <strong>de</strong> substitution <strong>et</strong> par analogie le polymorphisme. La<br />

clause « IS OF » perm<strong>et</strong> <strong>de</strong> limiter le principe <strong>de</strong> substitution à certains types.<br />

Les obj<strong>et</strong>s qui sont abrités dans un container super-type peuvent être accédés à l’ai<strong>de</strong> <strong>de</strong><br />

la fonction « TREAT ». C<strong>et</strong>te fonction cherche à modifier le type d’une expression par un<br />

autre type, généralement par un sous-type.<br />

1.19.2.8. Héritage <strong>et</strong> métho<strong>de</strong>s<br />

Les métho<strong>de</strong>s <strong>du</strong> super-type sont héritées dans tous les sous-types, la spécialisation <strong>de</strong>s<br />

sous-types s’effectue selon les règles <strong>de</strong> la programmation obj<strong>et</strong> :<br />

Surcharge <strong>de</strong>s métho<strong>de</strong>s <strong>et</strong> ré-implémentation.<br />

Métho<strong>de</strong> à signature variable.<br />

• Métho<strong>de</strong>s abstraites<br />

La clause « NOT INSTANTIABLE » dé<strong>fin</strong>it une métho<strong>de</strong> abstraite, par défaut celle ci est<br />

« INSTANTIABLE ». L’implémentation d’une métho<strong>de</strong> « NOT INSTANTIABLE » doit<br />

s’effectuer dans un sous-type <strong>de</strong> son arborescence. Si le sous-type <strong>de</strong> 1 er niveau<br />

n’implémente pas une métho<strong>de</strong> abstraite, elle doit tout <strong>de</strong> même être déclarée comme<br />

étant « NOT INSTANTIABLE ».<br />

• Surcharge, signatures variables <strong>et</strong> comportement <strong>de</strong>s métho<strong>de</strong>s héritées<br />

Les métho<strong>de</strong>s peuvent être surchargées à l’ai<strong>de</strong> <strong>de</strong> la clause « OVERRIDING ». Le soustype<br />

hérite alors <strong>de</strong> toutes les métho<strong>de</strong>s <strong>du</strong> super-type qu’elles soient « STATIC » ou<br />

« MEMBER ». Plusieurs métho<strong>de</strong>s <strong>de</strong> même nom mais avec une signature différente<br />

peuvent être dé<strong>fin</strong>ies.<br />

Une hiérarchie <strong>de</strong> type peut surcharger plusieurs fois la même métho<strong>de</strong>. Les<br />

conséquences lors <strong>de</strong> l’exécution seront les suivantes :<br />

Le type <strong>de</strong> l’instance <strong>de</strong> l’obj<strong>et</strong> désignera la métho<strong>de</strong> à utiliser.<br />

22.06.2005 49/78


C<strong>et</strong>te désignation s’effectuera lors <strong>de</strong> l’exécution <strong>et</strong> non lors <strong>de</strong> la compilation<br />

(résolution tardive).<br />

Une métho<strong>de</strong> « FINAL » ne pourra pas être surchargée dans ses sous-types. Par défaut<br />

une métho<strong>de</strong> est « NOT FINAL ».<br />

• Restriction à la surcharge<br />

Les métho<strong>de</strong>s <strong>de</strong> type « FINAL » ne peuvent évi<strong>de</strong>mment pas être surchargées.<br />

Une métho<strong>de</strong> « STATIC » <strong>du</strong> sous-type ne peut pas surcharger une métho<strong>de</strong><br />

« MEMBER » <strong>du</strong> super-type <strong>et</strong> inversement.<br />

Une métho<strong>de</strong> avec <strong>de</strong>s paramètres ayant une valeur par défaut (« DEFAULT<br />

VALUE ») peut être surchargée uniquement si les valeurs par défaut sont<br />

redé<strong>fin</strong>ies dans son ou ses sous-types.<br />

Une métho<strong>de</strong> « ORDER » ne peux pas être surchargée.<br />

1.19.3. Persistance<br />

A partir <strong>de</strong>s types créés, Oracle propose <strong>de</strong>ux manières d’implémenter <strong>de</strong>s obj<strong>et</strong>s<br />

persistant.<br />

• Céation d’une tables à partir <strong>du</strong> type. On nomme ces tables tables obj<strong>et</strong>s. Chaque<br />

insertion dans la table est donc une instanciation d’obj<strong>et</strong>.<br />

• Création d’une vue dont la structure est dé<strong>fin</strong>ie par le type <strong>et</strong> <strong>de</strong> tables relationnelles<br />

pour placer <strong>de</strong>s tuples. La vue est dé<strong>fin</strong>ie par une requête basée sur les tables<br />

relationnelles<br />

Dans les <strong>de</strong>ux cas, ce sont les tables (obj<strong>et</strong> ou relationnelles) qui suppoteront les<br />

contraintes déclaratives. Le choix d’une implémentation est donc déterminant pour<br />

décrire les métho<strong>de</strong>s <strong>et</strong> les contraintes procé<strong>du</strong>rales.<br />

1.19.3.1. Tables obj<strong>et</strong>s<br />

Si on uttilise les tables obj<strong>et</strong>s, on créer à partir d'un type une table obj<strong>et</strong> qui est un<br />

"container" capable d'assurer la persistance <strong>de</strong>s obj<strong>et</strong>s.<br />

Dans la déclaration <strong>de</strong> la table obj<strong>et</strong>, l’utilisation <strong>de</strong> la clause "SCOPE IS" limite la portée<br />

d'un attribut <strong>de</strong> type "REF" aux OID <strong>de</strong> la table référencée. Elle perm<strong>et</strong> d'améliorer<br />

l'intégrité référentielle. La clause SCOPE contrôle correctement l'ajout d'une valeur<br />

erronée qui référence (enfant sans père) mais n'assure pas la manipulation <strong>de</strong> l'obj<strong>et</strong><br />

référencé. (Suppression d'un père qui a <strong>de</strong>s enfants). Il est donc possible dans une base<br />

<strong>de</strong> données relationnelle obj<strong>et</strong>, qu’une référence ne pointe plus sur un obj<strong>et</strong> vali<strong>de</strong> <strong>du</strong><br />

container même si la clause SCOPE est explicite. De telles références sont nommées<br />

dangling REFs. Elles peuvent être détectées avec le prédicat IS DANGLING.<br />

Si la clause "WITH ROWID" qualifie attribut <strong>de</strong> type "REF", cela signifie que l’on stocke le<br />

"ROWID" <strong>du</strong> tuple avec l'OID dans l'attribut en question. Ceci perm<strong>et</strong> d'améliorer les<br />

performances <strong>de</strong> déférencement, mais utilise davantage d'espace mémoire.<br />

• Instanciation <strong>de</strong>s collections<br />

1.19.3.2. Vues obj<strong>et</strong>s<br />

22.06.2005 50/78


La secon<strong>de</strong> possibilité pour assurer la persistance <strong>de</strong>s obj<strong>et</strong>s est <strong>de</strong> construire une vue<br />

dont la structure est basé sur un type. Les obj<strong>et</strong>s seront stockés dans <strong>de</strong>s tables<br />

relationnels classiques.<br />

Le lien entre les tables (contenu <strong>de</strong>s obj<strong>et</strong>s) <strong>et</strong> la structure (type) est garanti par la<br />

requête dé<strong>fin</strong>issant la vue. L'OID peut être obtenu à partir <strong>de</strong> l'i<strong>de</strong>ntifiant <strong>de</strong> l'obj<strong>et</strong> (clé<br />

primaire <strong>de</strong> la table principale).<br />

Pour gérer les éléments multivalués comme les collections, on utilise <strong>de</strong>s requêtes<br />

imbriquées dans la requête <strong>de</strong> dé<strong>fin</strong>ition <strong>de</strong> la vue <strong>et</strong> les clauses CAST <strong>et</strong> MULTISET.<br />

CAST s'occupera <strong>de</strong> forcer l'élément r<strong>et</strong>ourné dans un type déclaré, alors que MULTISET<br />

prend en charge la création d'une collection (VARRAY ou Nested Table).<br />

1.19.3.3. Héritage <strong>et</strong> Vues Obj<strong>et</strong>s<br />

Dé<strong>fin</strong>ition<br />

Le principe <strong>de</strong> l’héritage <strong>de</strong>s vues obj<strong>et</strong>s se base sur un ensemble <strong>de</strong> vues obj<strong>et</strong>s qui sont<br />

constituées à partir <strong>de</strong> types différents issus d’une même arborescence.<br />

Règles<br />

• Une sous-vue qui hérite d’une super-vue doit avoir son équivalence dans une<br />

hiérarchie <strong>de</strong> type.<br />

• Une hiérarchie <strong>de</strong> vue peut avoir la racine au milieu d’une arborescence <strong>de</strong> type.<br />

• La racine d’une hiérarchie <strong>de</strong> vue est appelée « vue <strong>de</strong> base » ou « root view » en<br />

anglais.<br />

• Deux hiérarchies <strong>de</strong> vue obj<strong>et</strong> ne peuvent pas se baser sur le même type.<br />

• Toutes les vues d’une hiérarchie doivent se trouver dans le même schéma.<br />

• Le terme pour la dé<strong>fin</strong>ition <strong>de</strong> l’héritage <strong>de</strong> vue obj<strong>et</strong> est « UNDER »<br />

I<strong>de</strong>ntificateur d’obj<strong>et</strong>s (OID)<br />

La vue <strong>de</strong> base doit dé<strong>fin</strong>ir l’i<strong>de</strong>ntificateur <strong>de</strong> l’obj<strong>et</strong> (OID) <strong>et</strong> ne peut hériter d’aucune<br />

autre vue. L’OID doit être spécifié à l’ai<strong>de</strong> <strong>de</strong> la comman<strong>de</strong> « WITH OBJECT ID », si le<br />

système doit générer l’OID, il sera possible <strong>de</strong> créer une sous-vue uniquement si la vue<br />

<strong>de</strong> base est créée à partir d’une table obj<strong>et</strong> ou d’une vue obj<strong>et</strong> dont l’OID a été généré<br />

par le système. Une sous-vue ne peut évi<strong>de</strong>mment pas dé<strong>fin</strong>ir d’i<strong>de</strong>ntificateur d’obj<strong>et</strong><br />

(OID).<br />

A<strong>fin</strong> <strong>de</strong> perm<strong>et</strong>tre à une vue d’être modifiable sans l’utilisation <strong>de</strong>s triggers « INSTEAD<br />

OF », il faut que la requête qui décrit la vue respecte les contraintes suivantes :<br />

• Pas <strong>de</strong> jointures<br />

• Pas <strong>de</strong> s<strong>et</strong> operators<br />

• pas <strong>de</strong> aggregate functions<br />

• pas <strong>de</strong> GROUP BY, DISTINCT<br />

• pas <strong>de</strong> pseudocolumns<br />

• pas d’expressions<br />

Si une vue n’est pas modifiable il faut utiliser les triggers « INSTEAD OF ». Ce type <strong>de</strong><br />

trigger n’est pas hérité par les sous-vues. Ils doivent donc être redé<strong>fin</strong>i pour chaque<br />

sous-vue.<br />

Une vue obj<strong>et</strong> peut être <strong>de</strong> type abstrait. Le terme « NOT INSTANTIABLE » va la<br />

caractériser. Ceci existe a<strong>fin</strong> <strong>de</strong> pouvoir baser la vue sur un type abstrait.<br />

Lors <strong>de</strong> la sélection d’une vue obj<strong>et</strong>, tous les obj<strong>et</strong>s r<strong>et</strong>ournés peuvent être <strong>du</strong> type <strong>de</strong> la<br />

vue ou d’une <strong>de</strong> ses sous-vues. Les fonctions « VALUE », « REF » ou un ou plusieurs<br />

22.06.2005 51/78


attribut <strong>de</strong> la vue peuvent être employés lors <strong>de</strong> la sélection d’une vue obj<strong>et</strong>. A<strong>fin</strong><br />

d’exclure les obj<strong>et</strong>s appartenant aux sous-vue lors <strong>de</strong> la sélection, il faut utiliser le terme<br />

« ONLY » dans la requête.<br />

1.19.3.4. Modèles hiérarchiques <strong>de</strong> vues<br />

La conception d’une hiérarchie <strong>de</strong> vue peut influencer les performances <strong>de</strong>s opérations<br />

qui seront effectuées sur c<strong>et</strong>te structure <strong>de</strong> vues. C’est pourquoi il est conseillé d’utiliser<br />

un <strong>de</strong> ces trois modèle pour la mise en place d’une hiérarchie optimale :<br />

• Modèle Plat<br />

• Modèle Horizontal<br />

• Modèle Vertical<br />

Modèle Plat<br />

Toutes les vues <strong>et</strong> les sous-vues <strong>de</strong> ce modèle sont basées sur la même table, mais sur<br />

<strong>de</strong>s types différents dans une même arborescence. L’intérêt <strong>de</strong> ce type <strong>de</strong> modèle est<br />

qu’il rend la vue modifiable, en supportant les in<strong>de</strong>xes <strong>et</strong> les contraintes. Par contre le<br />

nombre total <strong>de</strong> colonnes différentes dans une hiérarchie <strong>de</strong> types est <strong>de</strong> 1000,<br />

puisqu’une table ne supporte que 1000 colonnes au maximum. Tous les attributs<br />

appartenant à une sous-vue <strong>de</strong> l’obj<strong>et</strong> seront <strong>de</strong> valeur NULL lorsque l’obj<strong>et</strong> sera d’un<br />

type hiérarchiquement supérieur.<br />

Modèle Horizontal<br />

Dans ce type <strong>de</strong> modèle, chaque vue <strong>et</strong> sous-vue est créée à partir <strong>de</strong> tables différentes<br />

<strong>et</strong> <strong>de</strong> types différents d’une même arborescence. e type <strong>de</strong> modèle est très efficace pour<br />

le type <strong>de</strong> sélection avec une restriction sur un sous-type (SELECT … FROM WHERE .. IS<br />

OF ONLY sous_type)<br />

Par contre, une sélection sans restriction (SELECT * FROM mavue) oblige le système à<br />

faire <strong>de</strong>s UNION pour obtenir le résultat escompté.<br />

Modèle Vertical<br />

Pour ce type <strong>de</strong> modèle, il y a une table pour chaque vue. Les attributs <strong>de</strong> ces tables<br />

doivent correspondre aux types ou sous-types sur lesquels les vues seront basées, plus<br />

l’attribut OID. Ce modèle perm<strong>et</strong> la création d’in<strong>de</strong>xes sur un attribut <strong>et</strong> d’imposer <strong>de</strong>s<br />

contraintes d’unicité sur les attributs. Ce type <strong>de</strong> modèle dispose <strong>de</strong>s propriétés inverses<br />

<strong>du</strong> modèle horizontal, puisque la jointure s’effectue entre la table représentant la vue <strong>de</strong><br />

base <strong>et</strong> sa sous-vue.<br />

Les droits<br />

Les droits d'accès sur les tables obj<strong>et</strong>s <strong>et</strong> vues obj<strong>et</strong>s est géré <strong>de</strong> manière classique avec<br />

<strong>de</strong>s GRANT <strong>et</strong> <strong>de</strong>s privilèges SELECT,INSERT,UPDATE <strong>et</strong> DELETE.<br />

Pour les métho<strong>de</strong>s, les mécanismes classiques <strong>du</strong> modèle obj<strong>et</strong> (private, public,<br />

protected) ne sont pas implémentés dans la version actuelle d'Oracle.<br />

Le privilège EXECUTE sur un type, perm<strong>et</strong> l'exécution <strong>de</strong> toutes ces métho<strong>de</strong>s.<br />

22.06.2005 52/78


Ces mécanismes simple perm<strong>et</strong>tent donc <strong>de</strong> m<strong>et</strong>tre en place un système garantissant ou<br />

brisant l'encapsulation <strong>de</strong>s obj<strong>et</strong>s, conformément au modèle <strong>de</strong>s BDOO10<br />

"Invoker_Rights_Clause" spécifie si les métho<strong>de</strong>s "MEMBER" d'une classe doivent être<br />

exécutées avec les privilèges <strong>et</strong> dans le schéma <strong>de</strong> leur propriétaire ou <strong>de</strong> l'utilisateur<br />

courant (CURRENT_USER)<br />

AUTHID CURRENT_USER Spécifie que les fonctions <strong>et</strong> procé<strong>du</strong>res<br />

"MEMBER" sont exécutées avec les<br />

privilèges <strong>de</strong> l'utilisateur courant.<br />

C<strong>et</strong>te clause crée un type "invoker-rights"<br />

AUTHID DEFINER Spécifie que les fonctions <strong>et</strong> procé<strong>du</strong>res<br />

"MEMBER" sont exécutées avec les<br />

privilèges <strong>du</strong> propriétaire <strong>du</strong> schéma dans<br />

lequel se trouvent les métho<strong>de</strong>s.<br />

1.19.4. Jpublisher<br />

22.06.2005 53/78<br />

Ceci est la clause par défaut.<br />

Jpublisher est un générateur <strong>de</strong> classe Java à partir <strong>de</strong>s types obj<strong>et</strong>s dé<strong>fin</strong>is dans la base<br />

<strong>de</strong> données. Il génère <strong>de</strong>s classes SQLJ dans le cas où il y a <strong>de</strong>s métho<strong>de</strong>s <strong>et</strong> <strong>de</strong>s class<br />

java sans métho<strong>de</strong>s dans les types. Les obj<strong>et</strong>s générés sont<br />

• Une classe Java représentant le type Oracle.<br />

C<strong>et</strong>te classe contient <strong>de</strong>s accesseurs s<strong>et</strong> <strong>et</strong> g<strong>et</strong> pour tous les attributs <strong>du</strong> type.<br />

• Il peut en outre générer <strong>de</strong>s classes représentant le type <strong>de</strong> la référence contenu<br />

dans un attribut<br />

C<strong>et</strong>te classe contient une métho<strong>de</strong> g<strong>et</strong>Value() qui rend une instance <strong>de</strong> l’obj<strong>et</strong> se<br />

trouvant dans la référence <strong>et</strong> un s<strong>et</strong>Value() a<strong>fin</strong> d’effectuer sa modification.<br />

• Pour les collections, il crée une classe qui les représente.<br />

C<strong>et</strong>te classe contient la métho<strong>de</strong> g<strong>et</strong>Array() a<strong>fin</strong> <strong>de</strong> récupérer la collection,<br />

s<strong>et</strong>Array() pour la modifier. A<strong>fin</strong> <strong>de</strong> modifier <strong>et</strong> <strong>de</strong> récupérer les éléments se<br />

trouvant dans la collection, Jpublisher génère les métho<strong>de</strong>s g<strong>et</strong>Elements() <strong>et</strong><br />

s<strong>et</strong>Elements<br />

• Elle implémente dans les classes générées l’interface OraData <strong>et</strong> l’interface<br />

OraDataFactory <strong>et</strong> la métho<strong>de</strong> OraDataFactory()<br />

1.20. Transformation <strong>de</strong>s règles<br />

1.20.1. Modèles <strong>de</strong> classes UML, respect <strong>de</strong>s<br />

cardinalités<br />

L’objectif <strong>de</strong> ce chapitre est d’évaluer les possibilités <strong>de</strong> génération <strong>de</strong> script DDL à partir<br />

d’un modèle <strong>de</strong> classe UML11. Dans le cadre <strong>du</strong> proj<strong>et</strong>, la source proposée est un fichier<br />

XMI, alors que pour <strong>de</strong>s raisons <strong>de</strong> compréhension, les cas traités ici ce feront<br />

10 BDOO : Base <strong>de</strong> Données Orientée Obj<strong>et</strong>, l'encapsulation est pénalisant pour le langage <strong>de</strong> requête<br />

11 Le modèle <strong>de</strong> classe UML n'est pas traité dans ce document, il est repris comme point <strong>de</strong> départ pour obtenir<br />

le script DDL après transformation.


directement <strong>de</strong>puis les schéma <strong>du</strong> modèle <strong>de</strong> classe. La transposition modèle <strong>de</strong> classe<br />

en script DDL fait partie selon nous <strong>de</strong> la <strong>phase</strong> II <strong>du</strong> proj<strong>et</strong>.<br />

De part les choix que nous proposons, le résultat <strong>du</strong> scritpt DDL sera une suite <strong>de</strong><br />

création <strong>de</strong> types dans un premier temps, <strong>et</strong> <strong>de</strong> création <strong>de</strong> table contraintes, basé sur<br />

ces types.<br />

Règles <strong>de</strong> passage entre niveaux d’abstraction.<br />

Il existe comme pour le modèle relationnel, <strong>de</strong>s règles <strong>de</strong> passage entre niveaux<br />

d’abstraction perm<strong>et</strong>tant <strong>de</strong> dé<strong>fin</strong>ir <strong>de</strong>s classes persistantes à partir <strong>du</strong> modèle<br />

conceptuel <strong>de</strong> données, soit le modèle <strong>de</strong> classe UML. Mais <strong>de</strong> part la richesse<br />

sémantique <strong>du</strong> modèle relationnel obj<strong>et</strong>, elles ne sont pas si rigoureuses que celle <strong>du</strong><br />

mon<strong>de</strong> relationnel.<br />

Règle 1<br />

Chaque entité <strong>du</strong> diagramme <strong>de</strong> classe UML <strong>de</strong>vient une classe. L’i<strong>de</strong>ntité <strong>de</strong>vient celui<br />

<strong>de</strong> la classe.<br />

Règle 2<br />

Une association 1-N/1-* entre <strong>de</strong>ux entités/classes peut se modéliser <strong>de</strong> trois manières<br />

dans le modèle obj<strong>et</strong>.<br />

• La classe fille migre dans la classe mère<br />

• Avec <strong>de</strong>ux classes dont l’une contient éventuellement une collection avec ou sans<br />

pointeurs<br />

• Avec trois classes ne contenant aucune collection<br />

Règle 3<br />

Une association N-N/*-* entre <strong>de</strong>ux entités/classes peut se modéliser <strong>de</strong> <strong>de</strong>ux manières<br />

dans le modèle obj<strong>et</strong>.<br />

• Avec <strong>de</strong>ux classes dont l’une contient une collection <strong>de</strong> pointeurs<br />

• Avec une troisième classe contenant éventuellement une collection <strong>de</strong> pointeurs<br />

Règle 4<br />

Une association N-aire peut se modéliser <strong>de</strong> <strong>de</strong>ux manières dans le modèle obj<strong>et</strong>.<br />

• Avec N classes dont l’une contient une collection <strong>de</strong> pointeurs<br />

• Avec une (N+1)ième classe contenant éventuellement une collection <strong>de</strong> pointeurs<br />

Règle 5<br />

Une association 1-1 entre <strong>de</strong>ux entités/classes peut se modéliser dans le modèle obj<strong>et</strong>.<br />

• Avec <strong>de</strong>ux classes sans collection <strong>et</strong> m<strong>et</strong>tant en œuvre <strong>de</strong>s pointeurs<br />

• Avec une troisième classe contenant <strong>de</strong>s pointeurs mais sans collection<br />

On remarque donc que les règles ne sont pas bijectives, <strong>et</strong> qu’elle laisse place à une libre<br />

interprétation <strong>du</strong> développeur. C<strong>et</strong> état n’est pas tolérable pour un automate comme un<br />

générateur.<br />

Nous nous proposons donc dans la suite <strong>du</strong> document d’approfondir les différents cas a<br />

<strong>fin</strong> <strong>de</strong> lever ces imprécisions en éliminant tout par à l’interprétation <strong>et</strong> à la suggestion.<br />

Tra<strong>du</strong>ction d’un lien <strong>de</strong> composition monovalué<br />

C1 1 0..1<br />

C2<br />

a<br />

b<br />

22.06.2005 54/78


Le lien <strong>de</strong> composition va se tra<strong>du</strong>ire en un attribut ast2 <strong>de</strong> type C2.<br />

CREATE TYPE c2 AS OBJECT<br />

( b Varchar(10)) ;<br />

CREATE TYPE c1 AS OBJECT<br />

( a Varchar(10),<br />

ast2 c2 ) ;<br />

Ici le seul problème concernant le script LDD à générer concerne l’ordonnancement <strong>de</strong> la<br />

création <strong>de</strong>s types. Une proposition à r<strong>et</strong>enir serait l’utilisation systématique <strong>de</strong>s types<br />

partiels en début <strong>de</strong> script. A noter que si la cardinalité minimum aurrait été 1 au lien <strong>du</strong><br />

0 <strong>de</strong> l’exemple, il faudrait générer une contrainte NOT NULL mais sur la table basé sur le<br />

type c1 <strong>et</strong> l’attribut ast2.<br />

Tra<strong>du</strong>ction d’un lien d’association monovalué<br />

Si on désire tra<strong>du</strong>ire un lien d’association d’un modèle <strong>de</strong> classe on doit résoudre<br />

l’épineux problème <strong>de</strong> la <strong>du</strong>alités <strong>de</strong>s paradigmes relationnelles <strong>et</strong> obj<strong>et</strong>s. En eff<strong>et</strong> le<br />

modèle obj<strong>et</strong> spécifie un système <strong>de</strong> lien avec une navigation directionnel, donc un lien<br />

d’association <strong>de</strong>vrait perm<strong>et</strong>tre par défaut <strong>de</strong> naviguer dans les <strong>de</strong>ux sens.<br />

C1<br />

a<br />

0..1<br />

La tra<strong>du</strong>ction <strong>du</strong> lien l’association dans un mon<strong>de</strong> navigationnel est une mise en place <strong>de</strong><br />

<strong>de</strong>ux liens monovalués réciproques leC1 <strong>et</strong> leC2. C<strong>et</strong>te combinaison nécessite la création<br />

<strong>de</strong> type partiel pour perm<strong>et</strong>tre les références croisées 12 .<br />

CREATE TYPE c2 ;<br />

CREATE TYPE c1 AS OBJECT<br />

( a Varchar(7),<br />

LeC2 REF c2 ) ;<br />

CREATE OR REPLACE c2 AS OBJECT<br />

( b Varchar(7),<br />

LeC1 REF c1 ) ;<br />

12 Le double référencement rend également plus compliqué l'effacement d'un type. Il faut utiliser l'instruction<br />

DROP TYPE nomtype FORCE. Le dictionnaire est alors incohérent<br />

22.06.2005 55/78<br />

1<br />

C2<br />

b


Sens <strong>de</strong> navigation imposée<br />

Pour spécifier le sens <strong>de</strong> navigation le modèle <strong>de</strong> classe UML dispose d'une notation<br />

précise. Il nous semble donc important <strong>de</strong> le spécifier clairement lors <strong>de</strong> la construction<br />

<strong>du</strong> modèle puisque le sens <strong>de</strong> navigation n’est pas spécifié, il doit être assuré dans les<br />

<strong>de</strong>ux sens. La solution proposée nous semble donc être la solution correct<br />

Dans le cas <strong>de</strong> l'implémentation avec une base <strong>de</strong> données relationnelle obj<strong>et</strong>, le langage<br />

<strong>de</strong> manipulation <strong>de</strong> type SQL dispose <strong>de</strong> l'opérateur <strong>de</strong> jointure qui ne nécessite pas un<br />

sens <strong>de</strong> navigation. Si nous disposons d'une base <strong>de</strong> données obj<strong>et</strong>, le langage <strong>de</strong><br />

requête n'est pas spécifié, <strong>et</strong> la navigation est alors primordiale. De plus si on désire<br />

obtenir un « mapping » automatique entre les classe <strong>du</strong> langage <strong>de</strong> programmation <strong>et</strong> les<br />

classes persistantes, il est impératifs qu’elles aient la même structure.<br />

Dans la suite <strong>du</strong> document, nous relèverons parfois ce problème <strong>de</strong> navigation pour<br />

certains points particuliers.<br />

C1<br />

C2<br />

0..1<br />

1<br />

a<br />

b<br />

Avec un sens <strong>de</strong> navigation imposé, l’association se tra<strong>du</strong>it par une simple mise en place<br />

d’un lien monovalué leC1. La cardinalité minimale 0 figure à la source <strong>du</strong> lien.<br />

CREATE TYPE c1 AS OBJECT<br />

(a Varchar(10) ) ;<br />

CREATE TYPE c2 AS OBJECT<br />

(b Varchar(10) ,<br />

LeC1 REF c1) ;<br />

C1<br />

C2<br />

0..1<br />

1<br />

a<br />

b<br />

Avec le sens <strong>de</strong> navigation imposé inverse, l’association se tra<strong>du</strong>it par un lien monovalué<br />

leC2, solution symétrique à la précé<strong>de</strong>nte1.<br />

CREATE OR REPLACE TYPE c2 AS OBJECT<br />

(b Varchar(10)) ;<br />

CREATE OR REPLACE TYPE c1 AS OBJECT<br />

(a Varchar(10) ) ;<br />

LeC2 REF c2) ;<br />

Selon les règles proposée (règle 5), l’utilisation d’une classe supplémentaire A <strong>et</strong> mise en<br />

place <strong>de</strong> <strong>de</strong>ux liens monovalués leC1 <strong>et</strong> leC2 est enviseageable. C<strong>et</strong>te solution appelée<br />

solution universelle nous semble à éviter puisqu'elle ne m<strong>et</strong>s pas en application les<br />

cardinalités, <strong>et</strong> interdit un mapping automatique.<br />

22.06.2005 56/78


Héritage<br />

Voici ici un exemple <strong>de</strong> tra<strong>du</strong>ction d’une relation d’héritage. A rappeler que la cible<br />

r<strong>et</strong>enue ne supporte pas l’héritage multiple.<br />

C2<br />

b<br />

C4<br />

d<br />

22.06.2005 57/78<br />

C1<br />

CREATE TYPE c1 AS OBJECT<br />

( a Varchar(10))<br />

NOT FINAL NOT INSTANTIABLE;<br />

CREATE TYPE c2 UNDER c1<br />

( b VARCHAR2(10)) NOT FINAL;<br />

a<br />

C3<br />

CREATE TYPE c3 UNDER c1<br />

( c VARCHAR2(10)) FINAL;<br />

CREATE TYPE c4 UNDER c2<br />

( d NUMBER) FINAL;<br />

Contraintes sur héritage<br />

B<br />

b<br />

A<br />

a<br />

c<br />

C<br />

c<br />

{contrainte}


On trouve la notation ci-<strong>de</strong>ssous dans le langage UML pour spécifier une contrainte sur<br />

l’héritage. Les différentes contraintes décrites sont :<br />

- Exclusion (disjonction sans couverture)<br />

- Totalité (non disjonction <strong>et</strong> couverture)<br />

- Partition (disjonction <strong>et</strong> couverture)<br />

La notion <strong>de</strong> couverture entraîne que la super-classe soit abstraite, alors la disjonction<br />

concerne l’i<strong>de</strong>ntifiant. Il semble donc que les contraintes d’héritage ne doivent pas être<br />

traitées <strong>de</strong> manières explicite lors <strong>du</strong> passage dans les différents niveaux d’abstractions.<br />

Mise en place <strong>de</strong> liens multivalués<br />

La mise en place d’un lien multivalué nécéssite la notion <strong>de</strong> collection. Oracle supporte<br />

<strong>de</strong>ux types <strong>de</strong> collections:<br />

• Tables imbriquées (NESTED TABLE)<br />

Une table imbriquée (TABLE OF) est une collection non ordonnée <strong>et</strong> non limitée<br />

d’éléments <strong>de</strong> même type. Elle est adaptée à la représentation d’un lien <strong>de</strong> cardinalité<br />

non dé<strong>fin</strong>ie, N<br />

• Tableaux prédimensionnés<br />

Un tableau prédimensionné (VARRAY) est une collection ordonnée <strong>et</strong> limitée d’éléments<br />

<strong>de</strong> même type. Elle est adaptée à la représentation d’un lien <strong>de</strong> cardinalité fixe (p ex : 3)<br />

Tra<strong>du</strong>ction d’un lien <strong>de</strong> composition multivalué<br />

Modèle <strong>de</strong> classe pour une cardinalité non dé<strong>fin</strong>ie<br />

C1<br />

De la composition l’attribut ast2 est <strong>de</strong> type ensemble C2<br />

CREATE OR REPLACE TYPE c2 AS OBJECT<br />

(b Varchar(10) ) ;<br />

CREATE OR REPLACE TYPE tc2 AS TABLE OF c2 ;<br />

CREATE OR REPLACE TYPE c2 AS OBJECT<br />

(a Varchar(10) ,<br />

ast2 tc2) ;<br />

22.06.2005 58/78<br />

a<br />

1 0..*<br />

C2<br />

b


Modèle <strong>de</strong> classe pour une cardinalité dé<strong>fin</strong>ie<br />

C1<br />

a<br />

De la composition l’attribut ast2 est <strong>de</strong> type ensemble C2 en respectant la cardinalité<br />

nb<br />

CREATE OR REPLACE TYPE c2 AS OBJECT<br />

(b Varchar(10) ) ;<br />

CREATE OR REPLACE TYPE tc2 AS VARRAY(nb)<br />

OF c2 ;<br />

CREATE OR REPLACE TYPE c2 AS OBJECT<br />

(a Varchar(10) ,<br />

ast2 tc2) ;<br />

Relation d’association <strong>de</strong> un à plusieurs<br />

C1<br />

On r<strong>et</strong>rouve ici ensemble les <strong>de</strong>ux problèmes précités dans les exemples précé<strong>de</strong>nts,<br />

soit :<br />

• Le sens <strong>de</strong> navigation<br />

• La dé<strong>fin</strong>ition (ou non) <strong>de</strong>s cardinalités<br />

Si l’association à une cardinalité non dé<strong>fin</strong>ie <strong>et</strong> que le sens <strong>de</strong> navigation est spécifié <strong>de</strong><br />

la fille à la mère, on se r<strong>et</strong>rouve dans le cas d’une tra<strong>du</strong>ction i<strong>de</strong>ntique au modèle<br />

relationnelle, soit la tra<strong>du</strong>ction <strong>de</strong> l’association en un attribut dans la classe fille qui<br />

référence la classe mère, soit :<br />

CREATE TYPE c2 AS OBJECT<br />

(b Varchar(10) ) ;<br />

CREATE TYPE c1 AS OBJECT<br />

(a Varchar(10) ,<br />

ast2 REF c2 ) ;<br />

Si le sens <strong>de</strong> navigation est inversé (<strong>de</strong> la mère à la fille), l’association va se tra<strong>du</strong>ire par<br />

la mise en place d’un lien multivalué. L’implémentation <strong>du</strong> type <strong>de</strong> collection dépendra si<br />

les cardinalités sont dé<strong>fin</strong>ies ou non.<br />

22.06.2005 59/78<br />

a<br />

1 0..nb<br />

* 1<br />

C2<br />

b<br />

C2<br />

b


Voici par exemple la mise en place d’un lien multivalué lesC1 en utilisant un tableau sans<br />

cardinalités.<br />

CREATE TYPE c1 AS OBJECT<br />

(a Varchar(10) ) ;<br />

CREATE TYPE pc1 AS OBJECT<br />

(atpc1 Ref c1 ) ;<br />

CREATE TYPE tpc1 AS<br />

TABLE OF pc1 ;<br />

CREATE TYPE c2 AS OBJECT<br />

(b Varchar(10) ,<br />

LesC1 REF tpc1) ;<br />

Si le sens <strong>de</strong> navigation n’est pas spécifié, l’association sera tra<strong>du</strong>ite par la mise en place<br />

d’un lien multivalué lesC1 <strong>et</strong> d ’un lien réciproque monovalué leC2. La navigation est<br />

possible avec c<strong>et</strong>te solution dans les <strong>de</strong>ux sens, la remarque émise lors <strong>de</strong> la<br />

transformation <strong>de</strong> la cardinalité 1-1 reste valable. C<strong>et</strong>te donc c<strong>et</strong>te solution qui est<br />

correct par rapport au modèle <strong>de</strong> classe proposé.<br />

Le co<strong>de</strong> LDD est une combinaison <strong>de</strong>s <strong>de</strong>ux exemples précé<strong>de</strong>nts.<br />

La solution universelle, soit l’utilisation d’une classe supplémentaire A <strong>et</strong> mise en place<br />

<strong>de</strong> <strong>de</strong>ux liens monovalués leC1 <strong>et</strong> leC2 est à nouveau à rej<strong>et</strong>er car elle ne reflète pas les<br />

cardinalités proposées. La navigation entre classes n'est possible qu'en partant <strong>de</strong> la<br />

classe A, ce qui n'a pas <strong>de</strong> sens. Pour perm<strong>et</strong>tre la navigation bidirectionnelle entre C1 <strong>et</strong><br />

C2 il faudrait ajouter <strong>de</strong>ux liens multivalués, une fois entre C1 <strong>et</strong> A <strong>et</strong> un second entre C2<br />

<strong>et</strong> A. Le modèle <strong>de</strong>vient alors particulièrement lourd.<br />

Transformation d’associations N-N sans propriétés<br />

C1<br />

a<br />

L’ensemble <strong>de</strong>s remarques faites pour les exemples précé<strong>de</strong>nts restes valable, la<br />

complexité est cumulative. La transformation <strong>de</strong> c<strong>et</strong>te association est toujours liés aux<br />

sens <strong>de</strong> navigation <strong>et</strong> à la dé<strong>fin</strong>ition <strong>de</strong>s cardinalités, mais les liens sont les <strong>de</strong>ux<br />

multivalués.<br />

Pour le diagramme ci-<strong>de</strong>ssus, soit pas <strong>de</strong> sens <strong>de</strong> navigation proposée, la solution la plus<br />

rigoureuse constitue à m<strong>et</strong>tre en place <strong>de</strong>ux liens multivalués réciproque lesC1 <strong>et</strong> lesC2.<br />

CREATE TYPE c1 AS OBJECT<br />

(a Varchar(10) ) ;<br />

CREATE TYPE pc1 AS OBJECT<br />

(atpc1 Ref c1 ) ;<br />

* 1..*<br />

22.06.2005 60/78<br />

C2<br />

b


CREATE TYPE tpc1 AS TABLE OF pc1 ;<br />

CREATE TYPE c2 AS OBJECT<br />

(b Varchar(10) ,<br />

LesC1 REF tpc1) ;<br />

CREATE TYPE pc2 AS OBJECT<br />

(atpc2 Ref c2 ) ;<br />

CREATE TYPE tpc2 AS TABLE OF pc2 ;<br />

CREATE OR REPLACE TYPE c1 AS OBJECT<br />

(a Varchar(10) ,<br />

LesC2 REF tpc2 ) ;<br />

La tra<strong>du</strong>ction d’une cardinalité dé<strong>fin</strong>ie est simple a m<strong>et</strong>tre en place avec un VARRAY sur<br />

le lien a la place <strong>du</strong> TABLE<br />

La solution universelle, soit l’utilisation d’une classe supplémentaire A <strong>et</strong> mise en place <strong>de</strong><br />

<strong>de</strong>ux liens monovalués leC1 <strong>et</strong> leC2 n’est toujours pas acceptable si l’on tien compte <strong>de</strong><br />

la remarque sur le sens <strong>de</strong> navigation. De par la lour<strong>de</strong>ur <strong>de</strong>s liens réciproques, nous<br />

proposons plutôt la solution précé<strong>de</strong>nte pour une association N-N sans propriétés.<br />

Transformation d’associations N-N avec propriétés<br />

C1<br />

a<br />

Dans ce cas, l’utilisation d’une classe supplémentaire A <strong>et</strong> mise en place <strong>de</strong> <strong>de</strong>ux liens<br />

monovalués leC1 <strong>et</strong> leC2 vers les classes C1 <strong>et</strong> C2 parrait naturelle, mais elle ne perm<strong>et</strong><br />

la navigation entre les classes qu'à partir <strong>de</strong> la classe association. Il est nécessaire <strong>de</strong><br />

tra<strong>du</strong>ire l’association en <strong>de</strong>s attributs <strong>de</strong> collections (lien multivalués) dans chaque<br />

classe.<br />

Le diagramme ci <strong>de</strong>ssous <strong>de</strong>vrait être tra<strong>du</strong>it avec le script DDL suivant<br />

CREATE TYPE c1 AS OBJECT<br />

(a Varchar(10) ) ;<br />

CREATE TYPE c2 AS OBJECT<br />

1..* 1..*<br />

22.06.2005 61/78<br />

A<br />

c<br />

b


(b Varchar(10) ),<br />

CREATE TYPE a AS OBJECT<br />

(c Varchar(10) ,<br />

LeC1 REF c1 ,<br />

LeC2 REF c2 ) ;<br />

CREATE TYPE pa AS OBJECT<br />

(atpa Ref a ) ;<br />

CREATE TYPE tpa AS TABLE OF pa ;<br />

CREATE OR REPLACE TYPE c1 AS OBJECT<br />

(a Varchar(10) ,<br />

LesA REF tpa) ;<br />

CREATE OR REPLACE TYPE c2 AS OBJECT<br />

(b Varchar(10) ,<br />

LesA REF tpa) ;<br />

Dans le cas <strong>de</strong> cardinalités dé<strong>fin</strong>ies, le script pourrait être quelque peu plus compliqué, si<br />

les cardinalités n’étaient pas i<strong>de</strong>ntiques.<br />

Le modèle <strong>de</strong> classe UML nous perm<strong>et</strong> <strong>de</strong> spécifié une association N-N avec (ou sans)<br />

propriétés, mais ou on désire privilégier fortement un sens <strong>de</strong> navigation. On utilise pour<br />

cela le cela le lien d'agrégation (symbole <strong>du</strong> diamant blanc).<br />

C1<br />

a<br />

Cela nous fournit une variante <strong>de</strong> modèle intéressante ou le lien est représentée par la<br />

structure A dans la classe C2 contient l’attribut c <strong>et</strong> le lien monovalué leC1 vers la classe<br />

C1 qui représente une association. La classe C2 est rattachée à c<strong>et</strong>te structure par le lien<br />

multivalué lesA.<br />

La structure contient :<br />

• les attributs <strong>de</strong> l’association ;<br />

• un lien monovalué vers la classe C1.<br />

1..* 1..*<br />

A<br />

c<br />

CREATE OR REPLACE TYPE c1 AS OBJECT<br />

(a Varchar(10) ) ;<br />

22.06.2005 62/78<br />

C2<br />

b


CREATE OR REPLACE TYPE A AS OBJECT<br />

(c Varchar(10) ,<br />

LeC1 REF c1 ) ;<br />

CREATE OR REPLACE TYPE tc AS TABLE OF A ;<br />

CREATE OR REPLACE TYPE c2 AS OBJECT<br />

(b Varchar(10) ,<br />

LesA tc ) ;<br />

On voit la puissance <strong>de</strong> <strong>de</strong>scription <strong>du</strong> modèle <strong>de</strong> classe <strong>du</strong> langage UML.<br />

La différentiation entre la composition (diamant noir) <strong>et</strong> l'agrégation (diamant blanc) est<br />

alors évi<strong>de</strong>nte pour la transformation d une association N-N avec (ou sans) propriétés,<br />

mais ou on désire privilégier fortement un sens <strong>de</strong> navigation.<br />

C1<br />

a<br />

Le lien est représentée par la structure A dans la classe C2 contient l’attribut c <strong>et</strong><br />

l’attribut leC1 <strong>de</strong> classe C1. C’est c<strong>et</strong>te fois une agrégation.<br />

CREATE OR REPLACE TYPE c1 AS OBJECT<br />

(a Varchar(10) ) ;<br />

CREATE OR REPLACE TYPE A AS OBJECT<br />

(c Varchar(10) ,<br />

LeC1 c1 ) ;<br />

CREATE OR REPLACE TYPE tc AS TABLE OF A ;<br />

CREATE OR REPLACE TYPE c2 AS OBJECT<br />

(b Varchar(10) ,<br />

LesA tc ) ;<br />

Transformation d’associations réflexives<br />

Les associations réflexives peuvent être binaires ou n-aires. Il convient alors d’utiliser<br />

une solution <strong>de</strong> transformation en fonction <strong>du</strong> type <strong>de</strong> l’association réflexive (1-1, 1-N, N-<br />

N ou n-aire).<br />

L’exemple traité ici est une transformation d’une association réflexive 1-N en raisonnant<br />

sur une seule classe.<br />

22.06.2005 63/78<br />

C<br />

a<br />

0..*<br />

1..* 1..1<br />

A<br />

c<br />

1<br />

C2<br />

b


Ici en exemple, utilisation d’un lien multivalué lesC <strong>et</strong> un lien inverse leC.<br />

CREATE TYPE c ;<br />

CREATE TYPE tc AS OBJECT (ast REF c ) ;<br />

CREATE OR REPLACE TYPE ttc AS TABLE OF tc;<br />

CREATE OR REPLACE TYPE c AS OBJECT<br />

(a Varchar(10) ,<br />

LeC REF c , -- ou tc<br />

LesC ttc ) ;<br />

Création d’obj<strong>et</strong>s persistants<br />

• En guise <strong>de</strong> rappel, pécisone encore ici qu’avec le modèle <strong>de</strong> Date <strong>et</strong> Darween, un<br />

obj<strong>et</strong> persistant ne peut exister que dans le contexte d’une table. Une table obj<strong>et</strong> est<br />

basé sur un type, le nom <strong>de</strong>s colonnes <strong>de</strong> la tables est repris <strong>de</strong>s attributs <strong>du</strong> type.<br />

Chaque obj<strong>et</strong> (ou tuple) possè<strong>de</strong> un i<strong>de</strong>ntificateur unique généré par le système<br />

(OID) qui pourra être référencé par REF. Un obj<strong>et</strong> persistant à donc <strong>de</strong>ux partie<br />

distincts, une référence, soit son OID, interrogeable par la fonction Ref() <strong>et</strong> une<br />

valeur, correspondant à l’ensembles <strong>de</strong> ses attributs, interrogeable par la fonction<br />

Value().<br />

Contraintes déclaratives<br />

Les contraintes déclarative doivent être placées sur les tables <strong>et</strong> non pas sur les types. A<br />

noter que le modèle relationnel obj<strong>et</strong> recouvre les différents contraintes <strong>du</strong> modèle<br />

relationnel, soit :<br />

• PRIMARY KEY<br />

• FOREIGN KEY<br />

• UNIQUE<br />

• NOT NULL<br />

• CHECK<br />

La notion <strong>de</strong> PRIMARY KEY ne doit pas être confon<strong>du</strong>e avec l’OID. Le modèle relationnel<br />

obj<strong>et</strong> propose en<strong>fin</strong> une solution élégante pour différentier formellement l’i<strong>de</strong>ntificateur<br />

<strong>de</strong> l’i<strong>de</strong>ntifiant.<br />

Nous préconisons donc d’utiliser l’OID comme i<strong>de</strong>ntificateur unique d’obj<strong>et</strong> persistant <strong>et</strong><br />

la contrainte PRIMARY KEY pour qualifié l’i<strong>de</strong>ntifiant.<br />

Dans ce cadre la notion <strong>de</strong> clé étrangère n’a pas lieu d’être puisque que la notion <strong>de</strong><br />

relation entre classe doit être assurée par <strong>de</strong>s références d’obj<strong>et</strong>s. Le respect <strong>de</strong><br />

l’intégrité référentielle sur les référence est assuré par la clause SCOPE.<br />

22.06.2005 64/78


Les clause UNIQUE <strong>et</strong> NOT NULL sont générées pour satisfaire les cardinalités, alors que<br />

la clause CHECK doit être récupérée par les dé<strong>fin</strong>itions OCL.<br />

Exemple <strong>de</strong> création d’une classe persistante simple « tc1 »<br />

CREATE TYPE c1 AS OBJECT<br />

(att1 Varchar(7) ,<br />

att2 Varchar(20) ) ;<br />

CREATE TABLE tc1 OF c1 ;<br />

ALTER TABLE tc1 ADD CONSTRAINT pk_tc1<br />

PRIMARY KEY (att1) ;<br />

ALTER TABLE tc1 MODIFY att2<br />

ADD CONSTRAINT nn_att2 NOT NULL ;<br />

Il aurait été possible <strong>de</strong> créer la table tc1 en une comman<strong>de</strong> en intégrant la création <strong>de</strong><br />

la contrainte <strong>de</strong> clé primaire, directement dans la création <strong>de</strong> la table. La syntaxe<br />

proposé est plus simple à gérée par un générateur, chaque information sémantique<br />

générant une comman<strong>de</strong>. A relever également que c<strong>et</strong>te métho<strong>de</strong> est généralement<br />

r<strong>et</strong>enue dans le mon<strong>de</strong> relationnel pour gérer l’ordonnancement <strong>de</strong>s contraintes, les clés<br />

primaires <strong>de</strong>vant impérativement être créées avant les clés étrangères.<br />

Dans le mon<strong>de</strong> relationnel obj<strong>et</strong>, l’intégralité étant géré par la clause SCOPE, c<strong>et</strong>te règle<br />

est un peu différente, puisque elle impose <strong>de</strong> gréer toutes les table dans une première<br />

<strong>phase</strong> <strong>et</strong> <strong>de</strong> modifier celles qui contiennent une (ou plusieurs) références.<br />

A noter également la mise <strong>de</strong> la contrainte NOT NULL sur un ordre <strong>de</strong> modification<br />

d’attribut <strong>et</strong> non pas d’ajout <strong>de</strong> contrainte. C<strong>et</strong>te syntaxe est incontournable pour ce type<br />

<strong>de</strong> contrainte, puisque celle ci est placée sur l’attribut <strong>et</strong> non pas sur la table. Les autres<br />

types <strong>de</strong> contraintes peuvent être placée sur la table.<br />

Exemple <strong>de</strong> transformation associations 1-N<br />

Le premier exemple prend un sens <strong>de</strong> navigation unique<br />

C1<br />

a<br />

b<br />

22.06.2005 65/78<br />

C<br />

att1<br />

att2<br />

1 1..*<br />

C2<br />

c<br />

d


L’association un à plusieur sera tra<strong>du</strong>ite en un lien simple monovalué, il en resultera <strong>de</strong>ux<br />

tables liées comme le schéma ci-<strong>de</strong>ssous :<br />

Création <strong>de</strong>s types<br />

TC1<br />

OID attributs<br />

22.06.2005 66/78<br />

TC2<br />

CREATE OR REPLACE TYPE c1 AS OBJECT<br />

(a Varchar(5) ,<br />

b Varchar(20) );<br />

CREATE OR REPLACE TYPE c2 AS OBJECT<br />

(c Varchar(5) ,<br />

d Varchar(20) ,<br />

leC1 REF c1 ) ;<br />

Création <strong>de</strong>s tables<br />

CREATE TABLE tc1 OF c1<br />

(CONSTRAINT pk_c1 PRIMARY KEY (a) ) ;<br />

CREATE TABLE tc2 OF c2<br />

(CONSTRAINT pk_c2 PRIMARY KEY (c) ,<br />

lec1 SCOPE IS tc1 ) ;<br />

OID attributs @tc1<br />

La clause SCOPE limite les valeurs <strong>de</strong> lec1 dans les valeurs existantes d’ OID <strong>de</strong> c1.<br />

Le second exemple utilise une navigation dans les <strong>de</strong>ux sens, <strong>de</strong> manière explicite.<br />

C1<br />

a<br />

b<br />

1 1..*<br />

C2<br />

c<br />

d


L’association un à plusieur sera tra<strong>du</strong>ite c<strong>et</strong>te fois comme le schéma ci-<strong>de</strong>ssous :<br />

TC1<br />

Création <strong>de</strong>s types<br />

OID attributs Tab_refs<br />

Tab_@ref<br />

CREATE TYPE c2 ;<br />

Tab_@ref<br />

22.06.2005 67/78<br />

TC2<br />

CREATE TYPE pc2 AS OBJECT (apc2 REF c2) ;<br />

CREATE TYPE tpc2 AS TABLE OF pc2 ;<br />

CREATE OR REPLACE TYPE c1 AS OBJECT<br />

(a Varchar(5) ,<br />

b Varchar(20) ,<br />

lesC2 tpc2 ) ;<br />

CREATE OR REPLACE TYPE c2 AS OBJECT<br />

(c Varchar(5) ,<br />

d Varchar(20) ,<br />

leC1 REF c1 ) ;<br />

OID attributs @ref<br />

Type partiel<br />

Type pointeur sur c2<br />

Type tableau <strong>de</strong> pointeurs sur c2<br />

Type c1 avec lesC2 tableau <strong>de</strong><br />

pointeurs sur c2<br />

Type c2 avec leC1 pointeurs sur c1


Création <strong>de</strong>s tables<br />

CREATE TABLE tc1 OF c1<br />

(CONSTRAINT pk_c1 PRIMARY KEY (a) )<br />

NESTED TABLE lesc2 STORE AS stab_lesc2 ;<br />

CREATE TABLE tc2 OF c2<br />

(CONSTRAINT pk_c2 PRIMARY KEY (c) ,<br />

lec1 SCOPE IS tc1 ) ;<br />

ALTER TABLE stab_lesc2<br />

ADD (SCOPE FOR (lesc2) IS tc2) ;<br />

1.20.2. Règles OCL<br />

1.20.3. Evaluation <strong>du</strong> mapping<br />

La technologie relationnel obj<strong>et</strong> est censé être un amalgame <strong>de</strong> l’obj<strong>et</strong> <strong>et</strong> <strong>du</strong> relationnel<br />

a<strong>fin</strong> <strong>de</strong> gar<strong>de</strong>r le meilleur <strong>de</strong> ces philosophies. L’avantage d’utiliser c<strong>et</strong>te technique est<br />

que tous les obj<strong>et</strong>s (data row ou obj<strong>et</strong>) persistants sont représentés dans la base <strong>de</strong><br />

données donc centralisé. En outre le ou les modèles persistant sont décrits à l’ai<strong>de</strong> <strong>de</strong>s<br />

méta-données <strong>de</strong> la base <strong>de</strong> données, ce qui <strong>de</strong>vrait perm<strong>et</strong>tre d’effectuer un mapping<br />

automatique <strong>et</strong> donc <strong>de</strong> rendre la persistance obj<strong>et</strong> transparente <strong>et</strong> facile à créer.<br />

Dans notre proj<strong>et</strong> le modèle relationnel-obj<strong>et</strong> sera utilisé comme modèle <strong>de</strong> persistance<br />

avec une approche <strong>de</strong>scendante <strong>de</strong> l’application. Les tests ont été faites à l’ai<strong>de</strong> d’une<br />

base <strong>de</strong> données Oralce9i <strong>et</strong> m<strong>et</strong> en application la partie théorique <strong>de</strong> ce document sur<br />

les types « obj<strong>et</strong>-relationnel Oracle9i» en outre elle utilise l’utilitaire Jpublisher a<strong>fin</strong> <strong>de</strong><br />

créer le lien (mapping) entre l’obj<strong>et</strong> <strong>et</strong> le relationnel.<br />

Pour ce mapping nous utilisons les composant suivant :<br />

• Type Oracles<br />

• Table obj<strong>et</strong><br />

• Type Java ou sqlj <strong>de</strong> mapping<br />

L’idée <strong>de</strong> ce concept étant <strong>de</strong> créer <strong>de</strong>s types obj<strong>et</strong>s représentant le modèle obj<strong>et</strong>.<br />

A l’ai<strong>de</strong> <strong>de</strong> ces types nous allons créer une structure <strong>de</strong> table obj<strong>et</strong> <strong>de</strong>vant stocker les<br />

données sous forme relationnelle obj<strong>et</strong>.<br />

Les Types Oracles vont aussi nous perm<strong>et</strong>tre <strong>de</strong> générer à l’ai<strong>de</strong> <strong>de</strong> Jpublisher les class<br />

Java <strong>du</strong> modèle obj<strong>et</strong> persistant qui vont accé<strong>de</strong>r aux tables obj<strong>et</strong>s pour manipuler les<br />

données. C<strong>et</strong>te structure a comme caractéristique d’être très simple <strong>et</strong> <strong>de</strong> perm<strong>et</strong>tre <strong>de</strong><br />

stocker les données sous une forme plus proche <strong>de</strong> l’obj<strong>et</strong>, Elle perm<strong>et</strong> en outre<br />

l’utilisation <strong>de</strong>s règles d’intégrité référentielle.<br />

Modèle Obj<strong>et</strong><br />

Type Oracle<br />

22.06.2005 68/78<br />

Type Java<br />

Table Obj<strong>et</strong><br />

Implémentation <strong>de</strong> la<br />

collection dans une<br />

table imbriquée<br />

Limitation <strong>de</strong>s<br />

valeurs <strong>de</strong>s cellules<br />

<strong>de</strong> la table<br />

imbriquée dans les<br />

OID existants <strong>de</strong><br />

tc1Type pointeur sur<br />

c2<br />

Transaction<br />

JDBC<br />

Approche<br />

Descendante


Après avoir mis en place la composition <strong>de</strong> la structure, nous allons <strong>de</strong>voir représenter le<br />

modèle obj<strong>et</strong> en créant les types correspondant.<br />

• Gestion <strong>de</strong>s relations N (Collections vs tables <strong>de</strong> liaisons)<br />

Pour la problématique concernant la transformation <strong>de</strong>s cardinalités <strong>de</strong> type N, notre cas<br />

exprime parfaitement les difficultés <strong>de</strong> transformation décrite dans ce document.<br />

Après avoir essayé différentes structures hiérarchiques, les constations suivantes sont<br />

apparues :<br />

• La relation N-N transformé sous la forme <strong>de</strong> collection pour gar<strong>de</strong>r la double<br />

navigabilité ne perm<strong>et</strong>tait pas l’utilisation <strong>de</strong> contrainte d’intégrité référentielle sur la<br />

structure <strong>de</strong> collection proposée par Oracle.<br />

• La relation N-N transformé sous la forme <strong>de</strong> collection pour gar<strong>de</strong>r la double<br />

navigabilité était très difficile à gérer.<br />

• La relations N-N sous la forme <strong>de</strong> collection faisant partie d’un sous-type contenu<br />

dans une table obj<strong>et</strong>s <strong>de</strong> type super types nous ont fait créer <strong>de</strong>s programmes<br />

PL/SQL <strong>de</strong> manipulations <strong>de</strong> données très compliquées <strong>et</strong> complexe à m<strong>et</strong>tre en<br />

place, donc contre pro<strong>du</strong>ctif.<br />

Ces constations pour la transformation <strong>de</strong>s liaisons avec une cardinalité N nous ont fait<br />

déci<strong>de</strong>r <strong>de</strong> ne pas utiliser les collections dans les tables obj<strong>et</strong>s <strong>et</strong> <strong>de</strong> m<strong>et</strong>tre en place une<br />

table <strong>de</strong> liaison contenant les référence. Ceci nous a permis d’utiliser les contraintes<br />

d’intégrité référentielles <strong>et</strong> d’éviter <strong>de</strong> <strong>de</strong>voir gérer <strong>de</strong>s collections qui comme vous l’avez<br />

compris sont très problématique. La table <strong>de</strong> liaison aura <strong>de</strong>s attributs représentant les<br />

références <strong>de</strong>s obj<strong>et</strong>s. Il aurait tout à fait été possible d’utiliser l’id généré <strong>de</strong>s tables<br />

pour faire c<strong>et</strong>te liaison mais pour notre exemple nous avons pensé utiliser la manière la<br />

plus obj<strong>et</strong> possible.<br />

• Composant <strong>et</strong> manipulation <strong>de</strong> données<br />

Le choix <strong>de</strong> la table <strong>de</strong> liaison dans la gestion <strong>de</strong>s relations <strong>de</strong> type N nous a en outre<br />

imposée la manière <strong>de</strong> manipuler les données faisant partie <strong>de</strong> ces relations.<br />

Pour ce faire nous avons utilisé les métho<strong>de</strong>s <strong>de</strong> type pour gérer la relation <strong>et</strong> renvoyer<br />

les données correspondant à la relation par le biais variable <strong>de</strong> type collection. Ceci<br />

présente l’avantage <strong>de</strong> ne pas utiliser <strong>de</strong> collections dans les structures <strong>et</strong> <strong>de</strong> tout <strong>de</strong><br />

même présenter au mon<strong>de</strong> obj<strong>et</strong> <strong>de</strong>s composants respectant la philosophie obj<strong>et</strong>.<br />

La gestion <strong>de</strong> l’ajout <strong>et</strong> suppression <strong>de</strong> données sur la relation se faisant avec la même<br />

philosophie. Voici la métho<strong>de</strong> que <strong>de</strong>vra implémenter un type Oracle <strong>de</strong>vant faire face à<br />

une relation<br />

Métho<strong>de</strong> renvoyant la liste d’obj<strong>et</strong>s <strong>de</strong> la liaison<br />

Métho<strong>de</strong> ajoutant un obj<strong>et</strong> à la liaison<br />

Métho<strong>de</strong> supprimant un obj<strong>et</strong> <strong>de</strong> la liaison<br />

Pour toutes les autres manipulations <strong>de</strong> données nous pouvons utiliser la manière<br />

standard c’est à dire <strong>de</strong>s comman<strong>de</strong>s sql qui manipulent les données directement <strong>de</strong>s<br />

tables obj<strong>et</strong>s <strong>de</strong>puis Java ou créer <strong>de</strong> métho<strong>de</strong> en capsulant les comman<strong>de</strong>s SQL ce qui<br />

nous ramènerait à la question si SQL est tolérable ou non au niveau <strong>de</strong> Java.<br />

22.06.2005 69/78


Un <strong>de</strong>s objectif <strong>de</strong> ce proj<strong>et</strong> est <strong>de</strong> manipuler les données uniquement sous la forme<br />

d’obj<strong>et</strong>s, donc la technique consiste à encapsuler les comman<strong>de</strong>s SQL dans <strong>de</strong>s métho<strong>de</strong>s<br />

<strong>de</strong> types. Ceci aura comme conséquences :<br />

• Le co<strong>de</strong> SQL se trouvera en capsule dans le type Oracle, il <strong>de</strong>viendra un service obj<strong>et</strong><br />

<strong>de</strong> la base <strong>de</strong> données réutilisable par plusieurs éléments.<br />

• Le développeur Java n’écrit plus <strong>de</strong> SQL.<br />

• La naissance d’un nouveau rôle pour le proj<strong>et</strong> « application DB développeur Oracle ».<br />

• Les queries doivent être développé par l’application DB développeur Oracle sur<br />

<strong>de</strong>man<strong>de</strong>.<br />

• L’apparition <strong>de</strong> standard <strong>de</strong> développements <strong>de</strong> types Oracle pour les métho<strong>de</strong>s<br />

Il faut donc que :<br />

• Le type doit avoir une métho<strong>de</strong> STATIC s’appelant store()<br />

• La métho<strong>de</strong> store doit renvoyer l’OID ou la référence base <strong>de</strong> données<br />

• La métho<strong>de</strong> store doit s’occuper <strong>de</strong> la persistance dans la base <strong>de</strong> données dans tous<br />

les cas <strong>de</strong> figure (Insert, Update)<br />

• Une métho<strong>de</strong> STATIC pour la suppression doit exister.<br />

C<strong>et</strong>te technique d’encapsulation peu avoir toutes les formes que l’on peut imaginer. Elle<br />

peut par exemple être utiliser pour offrire au développeur <strong>de</strong>s métho<strong>de</strong>s <strong>de</strong> queries<br />

optimisée. Il faut cependant constater que la mise en place d’une telle technique<br />

augmente le travail développement au niveau <strong>de</strong> la base <strong>de</strong> données <strong>et</strong> lie l’application<br />

au niveau <strong>de</strong> la persistance à la Base <strong>de</strong> données Oracle.<br />

Si vous ne désirez pas utiliser le métho<strong>de</strong> <strong>de</strong> type <strong>et</strong> l’encapsulation <strong>de</strong> comman<strong>de</strong>s dans<br />

les métho<strong>de</strong>s <strong>de</strong> types pour une raison ou pour une autre, il vous suffit d’utiliser les<br />

comman<strong>de</strong>s SQL dans le co<strong>de</strong> Java (manière standard).<br />

Une <strong>de</strong>s caractéristiques <strong>de</strong> la manipulation <strong>de</strong> données relationnelles obj<strong>et</strong>s <strong>de</strong> manière<br />

standard est que les comman<strong>de</strong>s SQL sont simplifiées, puisque plusieurs termes sont à<br />

disposition <strong>de</strong>s développeurs (VALUE, REF,…) pour effectuer <strong>de</strong>s insertions <strong>et</strong><br />

modifications <strong>de</strong>s obj<strong>et</strong>s se trouvant dans la base <strong>de</strong> données sans <strong>de</strong>voir spécifier tous<br />

les champs. Pour plus d’information il suffit <strong>de</strong> vous référer à la 1 ère partie <strong>de</strong> ce<br />

document traitant <strong>de</strong>s nouveautés sur les types relationnels obj<strong>et</strong>s.<br />

Il faut cependant faire remarquer que les triggers INSTEAD OF ne sont plus utilisé dans<br />

c<strong>et</strong>te structure puisque nous n’utilisons pas <strong>de</strong> composant vues obj<strong>et</strong>s.<br />

• Persistance d’une relation d’héritage<br />

L’héritage à l’ai<strong>de</strong> <strong>de</strong>s tables obj<strong>et</strong> peut être gérer <strong>de</strong> 2 manières différentes :<br />

A l’ai<strong>de</strong> 1 seul table <strong>de</strong> type <strong>du</strong> super-Types<br />

Chaque type <strong>et</strong> sous-type sont stocké dans une table différentes<br />

Pour notre exemples nous avons décidé d’utiliser la gestion à 1 seul table par hiérarchie.<br />

C<strong>et</strong>te décision est intervenu puisqu’elle simplifiait la gestion <strong>de</strong>s structures hiérarchique<br />

en outre, il est intéressant <strong>de</strong> pouvoir tester ces nouvelles fonctionnalité dans ce<br />

domaine <strong>de</strong> la base <strong>de</strong> données.<br />

Type1<br />

Type2 Type3<br />

Génère<br />

22.06.2005 70/78<br />

Table container <strong>de</strong><br />

type1, type2 <strong>et</strong><br />

type3


C<strong>et</strong>te manière <strong>de</strong> gérer l’héritage aura un impact sur la gestion <strong>de</strong>s relations N-N <strong>de</strong>s<br />

sous-types se trouvant dans la table container avec d’autres tables.<br />

Comme nous l’avons déjà dis, nous gérons les relations sous forme <strong>de</strong> références dans<br />

<strong>de</strong>s tables <strong>de</strong> liaisons. Par dé<strong>fin</strong>ition nous voulons que les références soit <strong>de</strong>s références<br />

<strong>du</strong> type impliqué dans la relation <strong>et</strong> pas <strong>de</strong> son super type.<br />

Cependant comme le container est <strong>du</strong> type super type (comme décidé précé<strong>de</strong>mment) le<br />

type <strong>de</strong> l’attribut appartenant à la table <strong>de</strong> liaison ne peut être que <strong>du</strong> type super type,<br />

ceci a<strong>fin</strong> <strong>de</strong> pouvoir m<strong>et</strong>tre en place une contrainte d’intégrité référentielle (FK) pour<br />

gérer la relation dans la table <strong>de</strong> liaison. Il faudrait donc pouvoir m<strong>et</strong>tre en place une<br />

restriction <strong>de</strong> substitution à l’ai<strong>de</strong> <strong>de</strong> la comman<strong>de</strong> IS OF sur l’attribut. Ceci n’étant pas<br />

applicable au type REF, il nous faut gérer c<strong>et</strong>te situation à l’ai<strong>de</strong> d’un trigger Before<br />

Insert sur la table <strong>de</strong> liaison donc par programmation.<br />

1.20.3.1. Constatations sur les outils <strong>de</strong> manipulations<br />

<strong>de</strong> composants R.O.<br />

• Problématique <strong>de</strong> manipulation <strong>de</strong>s composants<br />

Après nos tests il est apparu que l’utilisation <strong>de</strong>s types <strong>et</strong> <strong>de</strong>s composants relationnels<br />

obj<strong>et</strong>s mis à disposition par Oracle était très instable. C’est pourquoi le stockage <strong>de</strong><br />

données dans une structure <strong>de</strong> tables relationnel obj<strong>et</strong> ne serait pas judicieux <strong>et</strong> pas<br />

fiable. C<strong>et</strong>te fonction offerte par la base <strong>de</strong> données a bien évolué <strong>de</strong>puis sa première<br />

version mais beaucoup <strong>de</strong> travail reste à faire a<strong>fin</strong> que tous les problèmes soit corrigé.<br />

C’est pourquoi, nous conseillons l’utilisation <strong>de</strong>s types pour la construction <strong>de</strong> vues<br />

relationnels obj<strong>et</strong>s <strong>et</strong> l’utilisation d’une structure relationnelle standard pour la<br />

sauvegar<strong>de</strong> <strong>de</strong>s données. C<strong>et</strong>te stratégie va nous perm<strong>et</strong>tre d’obtenir les fonctionnalités<br />

obj<strong>et</strong>s au travers <strong>de</strong>s types <strong>et</strong> <strong>de</strong> pouvoir garantir la pérennité <strong>de</strong>s données.<br />

Les problèmes suivants sont à prendre en compte lors <strong>de</strong> la création <strong>de</strong>s structures <strong>et</strong> <strong>de</strong><br />

leur maintenance sous peine <strong>de</strong> <strong>de</strong>voir régénérer à chaque manipulation <strong>de</strong>s structures<br />

relationnelles obj<strong>et</strong>s <strong>de</strong> la base <strong>de</strong> données, ce qui dans le cadre <strong>du</strong> stockage <strong>de</strong> données<br />

sous forme <strong>de</strong> table serait un gros risque :<br />

• Doublage <strong>de</strong> métho<strong>de</strong>s :<br />

Le nombre <strong>de</strong> métho<strong>de</strong> double sur le type lorsque la comman<strong>de</strong> Alter type add attribut<br />

est utilisé.<br />

Solution : créer les métho<strong>de</strong>s après que tous les attributs soit ajouté<br />

• Perte d’attribut :<br />

Les types ayant comme attribut unique une référence sur un autre type per<strong>de</strong> l’attribut<br />

après la manipulation <strong>de</strong> <strong>du</strong> type référencé avec la comman<strong>de</strong> ALTER type.<br />

Solution : créer ces types ayant l’attribut après la <strong>de</strong>rnière manipulation <strong>du</strong> type en<br />

question.<br />

• Plusieurs niveau <strong>de</strong> collections :<br />

22.06.2005 71/78


L’utilisation d’une collection <strong>de</strong> type référence d’un type direct (Exemple REF Type1)<br />

comme attribut d’un type ne perm<strong>et</strong> pas à l’utilitaire JPublisher <strong>de</strong> générer le class<br />

correspondante en Java.<br />

Solution : créer un type intermédiaire ayant un attribut <strong>de</strong> type référence <strong>du</strong> type<br />

correspondant.<br />

• Non-héritage <strong>de</strong> métho<strong>de</strong>s :<br />

Dans une relation d’héritage lorsque nous créons les métho<strong>de</strong>s <strong>de</strong>s super-types à l’ai<strong>de</strong><br />

<strong>de</strong> la comman<strong>de</strong> ALTER type donc après la structure d’héritage <strong>et</strong> qu’un sous-type n’a<br />

pas eu besoin d’ajout <strong>de</strong> métho<strong>de</strong> il n’hérite d'aucune métho<strong>de</strong>.<br />

Solution : Créer le type après que les super-types soit compl<strong>et</strong>.<br />

• Dépendance cyclique <strong>de</strong>s paramètres <strong>de</strong> métho<strong>de</strong> :<br />

Lors <strong>de</strong> la conception <strong>de</strong> métho<strong>de</strong> d’encapsulation pour la gestion <strong>de</strong>s relations N-N il a<br />

été impossible d'utiliser un paramètre <strong>de</strong> fonction ou procé<strong>du</strong>re <strong>de</strong> type "type oracle"<br />

sous la forme cyclique. Puisque lorsqu’un Type que nous appellerons TY1 à une métho<strong>de</strong><br />

dont le paramètre est d'un type TY2 <strong>et</strong> que le type TY2 a une métho<strong>de</strong> ayant un<br />

paramètre <strong>de</strong> type TY1, la base <strong>de</strong> données Oracle interprète cela comme une<br />

dépendance cyclique <strong>et</strong> ém<strong>et</strong> une erreur ORA. Il conseille alors d'utiliser le type REF pour<br />

casser ce cycle. Cependant lorsque c<strong>et</strong>te solution est mise en place il y une erreur interne<br />

ORA <strong>du</strong> moteur la base <strong>de</strong> données il est donc impossible <strong>de</strong> m<strong>et</strong>tre en place une<br />

stratégie complètement obj<strong>et</strong>.<br />

Solution : Elle consiste à utiliser l'id créer pour i<strong>de</strong>ntifier uniquement comme (C.f<br />

paragraphe suivant I<strong>de</strong>ntification obj<strong>et</strong>), comme il est <strong>de</strong> type numérique cela interrompt<br />

la dépendance cyclique <strong>et</strong> nous pouvons m<strong>et</strong>tre en place la stratégie désirée.<br />

• Problématique <strong>de</strong> l’i<strong>de</strong>ntification d’obj<strong>et</strong><br />

Lors <strong>de</strong> la conception <strong>de</strong>s différentes structures base <strong>de</strong> données avec une pensée obj<strong>et</strong>s<br />

nous avons cru qu’il était possible d’implémenter complètement le paradigme obj<strong>et</strong>.<br />

Nous avons été déçus <strong>de</strong> voir que ce principe était impossible à réaliser :<br />

« Tout obj<strong>et</strong> est i<strong>de</strong>ntifié uniquement » .<br />

Au début <strong>de</strong>s tests nous pensions que l’i<strong>de</strong>ntification d’un obj<strong>et</strong> aurait été prise en main<br />

par la base <strong>de</strong> données Oracle. OID <strong>de</strong>vant remplir ce rôle.<br />

Après quelques essais nous avons très vite abandonné c<strong>et</strong>te idée <strong>et</strong> nos avons décidé <strong>de</strong><br />

m<strong>et</strong>tre en place une clé primaire unique générée par une séquence base <strong>de</strong> données<br />

(gestion standard <strong>de</strong> l’unicité <strong>de</strong>s clés).<br />

C<strong>et</strong>te décision à été prise après avoir remarqué qu’il était impossible d’obtenir une<br />

référence base <strong>de</strong> données sans utiliser la comman<strong>de</strong> « select ref(x)…. ».<br />

La situation qui nous a posé problème était la suivante :<br />

• Deman<strong>de</strong>r à l’obj<strong>et</strong> sa propre référence (OID ) a<strong>fin</strong> d’accé<strong>de</strong>r d’autres obj<strong>et</strong>s ou il<br />

était référencé<br />

Comme nous n’avions <strong>de</strong> clé primaire <strong>et</strong> qu’il était impossible d’utiliser la comman<strong>de</strong><br />

« select » pour i<strong>de</strong>ntifier l’obj<strong>et</strong> <strong>de</strong> façon certaine, nous avons exploré d’autres solutions<br />

qui n’ont pas donné le résultat escompter.<br />

Les solutions essayées sont les suivantes :<br />

• Création d’une métho<strong>de</strong> membre revoyant avec la comman<strong>de</strong> SELF la référence <strong>de</strong><br />

l’obj<strong>et</strong>. SELF étant un paramètre représentant l’obj<strong>et</strong> <strong>et</strong> pas sa référence ceci est<br />

impossible<br />

• Recherche dans les tables system pour trouver l’OID. Trop long <strong>et</strong> impossible à<br />

réaliser<br />

22.06.2005 72/78


• Recherche d’une fonction fournie par Oracle pour faire ce travail. Ceci était Inexistant<br />

• Support Oracle. Incompétent dans ce domaine<br />

Nous espérons qu’Oracle fournira une telle fonctionnalité dans le futur. Ceci serait la<br />

<strong>de</strong>rnière étape vers l’implantation <strong>du</strong> concept obj<strong>et</strong>. En attendant nous conseillons<br />

l’utilisation <strong>de</strong>s clés primaires générées pour i<strong>de</strong>ntifier uniquement les obj<strong>et</strong>s. Ceci ne<br />

signifie pas que les relations ne peuvent pas être sous la forme <strong>de</strong> référence mais que<br />

l’obj<strong>et</strong> est i<strong>de</strong>ntifié par un attribut i<strong>de</strong>ntifiant pour pouvoir le r<strong>et</strong>rouver à tout moment<br />

dans la base <strong>de</strong> données.<br />

Transformation <strong>de</strong>s règles OCL<br />

La transformation <strong>de</strong>s règles OCL en trigger ou en contraintes déclaratives dans un schéma<br />

relationnel-obj<strong>et</strong> Oracle 9i sera une <strong>de</strong>s tâches importantes <strong>de</strong> la <strong>phase</strong> 2 <strong>du</strong> proj<strong>et</strong>.<br />

Nous présentons ci-<strong>de</strong>ssous une exemple simple <strong>de</strong> ce qu’il sera possible <strong>de</strong> faire avec le<br />

générateur en guise d’amuse-bouche.<br />

A partir d’une contrainte OCL <strong>et</strong> d’une classe UML, nous générerons un fichier XMI avec<br />

Poseidon for UML<br />

context Article inv :<br />

prix > 0.0<br />

Le contenu <strong>de</strong> ce fichier XMI sera analysé par le générateur <strong>et</strong> pro<strong>du</strong>ira les <strong>de</strong>ux scripts SQL-<br />

DDL suivants :<br />

• Script <strong>de</strong> création <strong>de</strong>s types<br />

CREATE TYPE ty_article AS OBJECT<br />

(numero Number(9) ,<br />

prix Number(5.2) );<br />

• Script <strong>de</strong> création <strong>de</strong>s tables<br />

CREATE TABLE article OF ty_article<br />

CONSTRAINT pk_article PRIMARY KEY (numero) ) ;<br />

ALTER TABLE article ADD CONSTRAINT ch_pric<br />

CHECK (prix > 0.0);<br />

1.21. Annexes<br />

1.21.1. Scripts DDL <strong>du</strong> modèle exemple<br />

1.21.1.1. Création <strong>de</strong>s types<br />

22.06.2005 73/78


-- Creation <strong>de</strong> la base exemple<br />

DROP TYPE ty_stockitem FORCE ;<br />

DROP TYPE ty_ligItem FORCE ;<br />

DROP TYPE ty_Lis_ligItem FORCE ;<br />

DROP TYPE ty_lis_telephone FORCE ;<br />

DROP TYPE ty_addresse FORCE ;<br />

DROP TYPE ty_genre FORCE ;<br />

DROP TYPE ty_client FORCE ;<br />

DROP TYPE ty_personne FORCE ;<br />

DROP TYPE ty_entreprise FORCE ;<br />

DROP TYPE ty_comman<strong>de</strong> FORCE ;<br />

------------------------------------<br />

CREATE TYPE ty_StockItem AS OBJECT (<br />

numStock Number,<br />

Prix Number,<br />

Taxe Number<br />

);<br />

/<br />

CREATE TYPE ty_ligItem AS OBJECT (<br />

numligitem Number,<br />

ref_stock REF ty_StockItem,<br />

Quantite Number,<br />

Rabais Number<br />

);<br />

/<br />

CREATE TYPE ty_Lis_ligItem AS TABLE OF ty_LigItem;<br />

/<br />

CREATE TYPE ty_lis_telephone AS VARRAY(3) OF Varchar2(20);<br />

/<br />

CREATE TYPE ty_addresse AS OBJECT (<br />

Rue Varchar2(200),<br />

Ville Varchar2(200),<br />

Canton Char(2),<br />

co<strong>de</strong> Varchar2(20)<br />

)<br />

/<br />

CREATE TYPE ty_genre AS OBJECT (<br />

genre Varchar2(200)<br />

)<br />

/<br />

CREATE TYPE ty_client AS OBJECT (<br />

numclient Number,<br />

nomclient Varchar2(200),<br />

addresse ty_Addresse,<br />

lis_telephone ty_lis_telephone<br />

)<br />

NOT INSTANTIABLE<br />

NOT FINAL;<br />

/<br />

22.06.2005 74/78


CREATE TYPE ty_personne UNDER ty_client (<br />

ref_genre REF ty_genre<br />

)<br />

INSTANTIABLE<br />

FINAL;<br />

/<br />

CREATE TYPE ty_entreprise UNDER ty_client (<br />

chiffreaffaire Number<br />

)<br />

INSTANTIABLE<br />

FINAL;<br />

/<br />

CREATE TYPE ty_comman<strong>de</strong> AUTHID CURRENT_USER AS OBJECT (<br />

numcom Number,<br />

ref_client REF ty_client,<br />

Date_comman<strong>de</strong> Date,<br />

Date_livraison Date,<br />

tab_LigItem ty_lis_ligitem,<br />

addresse_livraison ty_Addresse<br />

);<br />

/<br />

1.21.1.2. Création <strong>de</strong>s tables<br />

-- Creation <strong>de</strong> la base exemple<br />

------------------------------------<br />

CREATE TABLE to_genre OF ty_genre<br />

OBJECT IDENTIFIER IS SYSTEM GENERATED ;<br />

CREATE TABLE to_stockitem OF ty_StockItem<br />

( numStock PRIMARY KEY)<br />

OBJECT IDENTIFIER IS PRIMARY KEY ;<br />

CREATE TABLE to_client OF ty_client<br />

( numclient PRIMARY KEY)<br />

OBJECT IDENTIFIER IS PRIMARY KEY ;<br />

CREATE TABLE to_comman<strong>de</strong> OF ty_comman<strong>de</strong> (<br />

PRIMARY KEY (numcom),<br />

FOREIGN KEY (ref_client) REFERENCES to_client)<br />

OBJECT IDENTIFIER IS PRIMARY KEY<br />

NESTED TABLE tab_ligItem STORE AS PoLine_ntab (<br />

(PRIMARY KEY(NESTED_TABLE_ID, numligitem))<br />

ORGANIZATION INDEX COMPRESS)<br />

RETURN AS LOCATOR<br />

/<br />

ALTER TABLE poline_ntab<br />

ADD (SCOPE FOR (ref_stock) IS to_stockitem ) ;<br />

22.06.2005 75/78


1.21.1.3. Exemple <strong>de</strong> peuplement pour tests<br />

---Nécéssite la version 9.2<br />

-- Ne fonctionne pas en 9.0 !!------<br />

-- Table to_genre<br />

INSERT INTO to_genre VALUES ('Féminin');<br />

INSERT INTO to_genre VALUES ('Masculin');<br />

-- Table to_stockitem<br />

INSERT INTO to_stockitem VALUES(1004, 6750.00, 2) ;<br />

INSERT INTO to_stockitem VALUES(1011, 4500.23, 2) ;<br />

INSERT INTO to_stockitem VALUES(1534, 2234.00, 2) ;<br />

INSERT INTO to_stockitem VALUES(1535, 3456.23, 2) ;<br />

-- Table to_client<br />

---- Personne<br />

INSERT INTO to_client<br />

SELECT ty_personne( 1,<br />

'Jean Nance',<br />

ty_Addresse('2 Pommiers',<br />

'Neuchâtel',<br />

'NE',<br />

'2000'),<br />

ty_lis_telephone('032/234.23.12'),<br />

Ref(g)<br />

)<br />

FROM to_genre g<br />

WHERE genre = 'Masculin' ;<br />

---- Entreprise<br />

INSERT INTO to_client<br />

VALUES (ty_entreprise( 2,<br />

'Edison',<br />

ty_Addresse('3 Zone in<strong>du</strong>strielle',<br />

'La Chaux-<strong>de</strong>-Fonds',<br />

'NE',<br />

'2300'),<br />

ty_lis_telephone('032/226.12.23','032/121.65.32'),<br />

120<br />

)<br />

) ;<br />

--------------------<br />

INSERT INTO to_comman<strong>de</strong><br />

SELECT 1001,<br />

REF(cli),<br />

SYSDATE,<br />

To_date('11-09-2003','DD-MM-YYYY'),<br />

ty_lis_ligitem(),<br />

NULL<br />

FROM to_client cli<br />

WHERE cli.numclient = 1 ;<br />

22.06.2005 76/78


INSERT INTO TABLE (<br />

SELECT c.tab_ligitem<br />

FROM to_comman<strong>de</strong> c<br />

WHERE c.numcom = 1001<br />

)<br />

SELECT 01,<br />

REF(S),<br />

12,<br />

0<br />

FROM to_stockitem S<br />

WHERE S.numStock = 1534 ;<br />

INSERT INTO TABLE (<br />

SELECT c.tab_ligitem<br />

FROM to_comman<strong>de</strong> c<br />

WHERE c.numcom = 1001)<br />

VALUES (01,null,12,0);<br />

-- OK<br />

DELETE FROM TABLE (<br />

SELECT c.tab_ligitem<br />

FROM to_comman<strong>de</strong> c<br />

WHERE c.numcom = 1001)<br />

WHERE numligitem = 1 ;<br />

*/<br />

----<br />

INSERT INTO to_comman<strong>de</strong><br />

SELECT 2001,<br />

REF(cli),<br />

SYSDATE,<br />

To_date('20-05-2003','DD-MM-YYYY'),<br />

ty_lis_ligitem(),<br />

ty_Addresse('3 Zone in<strong>du</strong>strielle',<br />

'La Chaux-<strong>de</strong>-Fonds',<br />

'NE',<br />

'2300')<br />

FROM to_client cli<br />

WHERE cli.numclient = 2 ;<br />

INSERT INTO TABLE (<br />

SELECT c.tab_ligitem<br />

FROM to_comman<strong>de</strong> c<br />

WHERE c.numcom = 1001<br />

)<br />

SELECT 02,<br />

REF(S),<br />

10,<br />

10<br />

FROM to_stockitem S<br />

WHERE S.numStock = 1535 ;<br />

INSERT INTO TABLE (<br />

SELECT c.tab_ligitem<br />

FROM to_comman<strong>de</strong> c<br />

WHERE c.numcom = 2001<br />

22.06.2005 77/78


)<br />

SELECT 10,<br />

REF(S),<br />

1,<br />

0<br />

FROM to_stockitem S<br />

WHERE S.numStock = 1004 ;<br />

-- Autre syntaxe, meilleur<br />

INSERT INTO TABLE (<br />

SELECT c.tab_ligitem<br />

FROM to_comman<strong>de</strong> c<br />

WHERE c.numcom = 2001<br />

)<br />

VALUES (11,<br />

(SELECT REF(S)<br />

FROM to_stockitem S<br />

WHERE S.numStock = 1011) ,<br />

2,<br />

1 ) ;<br />

COMMIT ;<br />

22.06.2005 78/78

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!