Upload
others
View
4
Download
0
Embed Size (px)
Citation preview
Introduction au Système objetSystème O2
Base de données à objetsconforme au standard industriel
ODMG
André Gamache, professeur associéDépartement d'informatique et de génie logicielFaculté des sciences et de génieUniversité Laval. Québec, Qc, Canada, G1K 7P4Courriel: [email protected]
Les objectifs de ce module:
- Découvrir quelques fonctionnalités d’un SGBD objet, presque conforme aux normes ODMG.
- Furmuler quelques diagrammes de classe UML avec O2
- Survoler l’interrogation de la base objets avec un SQL orienté objet proposé par O2
Pour illustrer les recommandations ODMG, le système O2 sera brièvement étudié en soulignant au passage la simplicité de ce système.
Objet O2
Modèle O2: fondé sur la notion d'objet et de valeurObjet := oid + données typées + opérations
(signature) + code d’implémentation des opérations (body)
Valeur : type instancié ou objet sans son oid
• Types simples, complexes et d’usager (TAD)
Chaque type = structure avec une valeur (pas de méthodes).
Classe O2
ClasseLes objets sont créés selon le moule d’une classe soit une
structure générique ; ils sont regroupés par classification dans une structure d'extension (qui sert de container) de structure d’ensemble;
Une classe O2 a un type et des méthodes partagés par tous lesobjets de sa classe.
Aucun attribut (ou méthode) de classe n’est factorisé au niveaude la classe (contrairement à certains langages objets nonpersistants)
Page 5
Système de typage extensible :
1. Number(x,0) : int long ou int court ; 2. Real : float ou number (x,y)3. TAD défini sur les types atomiques et complexes
Héritage simple et multiple:
Typage et héritage O2
A
B C
D
Indépendant du langage de programmation:Types, héritage et persistance ne dépendent pas du langage deProgrammation (mais du SGBDOO). Mapping à prévoir lors du transfert d'unobjet vers L3G car les structures ou types d'implémentation sont très souvent différents de ceux du langage de traitement.
Page 6
Architecture générale du système O2
Moteur O2
Base O2
(rangement des objets
Serveur de pages)
O2C OQL C++ CMoteur O2:
Système objet ODMGToutes les fonctionnalités du SGBDArchitecture client/serveurTransactionnel : court et longVersionnage des objetsPersistance assuréeReprise sur panne
Scaling par ajout de modules
Page 7
Client et serveur O2
Client (Unix ou Windows)
Cache des pages objets
Serveur O2
Cache page-serveur
Système E/S
Gestion des verrous de page
Table page-verrous
O2: Serveur de pages
Page d’objets
Page 8
Autres architectures: Serveur d’objets (système Orion)
1- Serveur d’objets
Application Gestionnaire d’objets
Côté clientCôté serveur
Serveur d’objetsrequête
objetRôle du serveur : Exécution de la requête, gestion de l’espace disque, des
verrous, de l’intégrité, exécution des procédure stockées.
Rôle du gestionnaire (côté client):Gestion de la transaction, interface avec le L3G.
Avantages: 1. Pas d’accaparement inutile d’objets : seul l’objet traité est verrouillé;2. Distribution plus simple des objets: les objets sont distribués à la
demande;3. Évolution de l’objet plus facile à gérer: l’agrandissement de la structure
de l’objet ne pose pas de problème d’encombrement local. L’objet étant stocké au niveau du serveur!
Page 9
Autres architectures: serveur de pages (cas O2)
2- Serveur de pages
Application Gestionnaire de pages
Côté clientCôté serveur
Serveur de pagesadresses
Page demandée
Rôle du serveur : gestion de l’espace disque, des verrous, de l’intégrité
Rôle du gestionnaire (côté client) : le traitement d’accès à un objet (mapping) est fait par le client (qui effectue le gros du traitement)
Avantages:1. Implémentation plus simple2. Concurrence des accès plus facile à gérer
Page 10
Persistance des objets O2
Objet persistant : Objet stocké dans la base de données (sur disque) dont la durée de vie est supérieure au programme qui l’a créé ou modifié.
-- Un objet créé et rendu persistant n’a pas besoin d’être écrit explicitement sur disque par l’application.
Dans O2 : un objet est persistant si rangé dans son extension (container) ou nommé par un nom global inscrit dans le DD ou inséré dans un autre objet persistant.
Objet transitoire (transient) : Objet de mémoire, dont la durée de vie ne dépasse pas celle du programme qui l'a créé. Objet de service!
Page 11
Interlude technique La mutation de pointeurs
• La mutation des pointeurs concerne l’accès aux objets persistants stockés dans la RAM d’un client (contexte serveur de pages) ou d’un serveur (contexte serveur d’objets).
• La référence d’un objet à un autre objet dans la base (sur disque) est faite avec l’oid (cas O2 ≈ Oracle).
• L’accès par une application à un objet en RAM doit utiliser une adresse physique… la seule façon finalement d'y accéder!
Page 12
Mutation (swizzling ) : oid -> adresse physique
• Pour réaliser un accès, les oids sont transformés en autant d'adresses physiques de la RAM.
Une référence par oid
Une référence par adresse physique
oid2adr_oid8
adr_oid5
oid5adr_oid4
oid8oid4
oid8oid5
oid4
oid2 oid4 oid5
oid8
Page 13
Serveur de pages: Accès à un objet : swizzling
La mutation (swizzling) est effectuée et gérée par le client du SGBDOO (cas du serveur de pages)
RAM de l’application
Disqueoid1
Page 34
oid1
1-Read page vers la cache
2- Mutation des oid -> pointeurs
oid4
oid4
cache
3-accès à l’objet par pointeur
4- mutation des pointeurs en oid
Code de la logique de traitement
L’application trouve les objets par fouille séquentielle dans la page.
Page 14
Implémentation de la localisation des objets
• Lors d’un référencement d’objet par oid:1- Si objet est dans la RAM: la table ORM est consultée pour trouver
l’adresse RAM de l’objet.
Évaluation de la variable : x.objet.v1 avec x de type objet
ORMOid adr RAM
…oid2 FB234Aoid4 4AF2233oid8 8FB2865oid5 93422FF
oid8oid5
oid4
Objet
oid8
Objet en RAM
Page 15
Mécanismes de localisation des objets (suite)
2- Objet est absent de la RAM: la table ORM est consultée pour trouver que oid8 est absent
Évaluation de la variable : x.objet.v1 avec x de type objet
ORMoid adr RAM
…oid2 FB234Aoid4 4AF2233oid5 93422FF
v1 : oid8oid5
oid4
Objet
oid8
Page 16
La table OP d’accès aux objets
• Chaque objet persistant de la BD est inscrit dans une autre table OP.
• La table OP ( volumineuse) est partiellement en RAM et swappée par l'initiative du noyau selon les besoins.
OP
oid adr disque
…
oid8 129745
…
Page 17
Transfert de l’objet oid8 (suite)
1- La table OP (Table des Objets Persistants) est consultée pour trouver l’adresse de oid8 sur disque.
2- L’objet oid8 est transféré et inscrit dans la table ORM
ORMOid adr RAM
…oid2 FB234Aoid4 4AF2233oid5 93422FFoid8 F3B255
v1 : oid8oid5
oid4
Objet
oid8
Évaluation de la variable : x.objet.v1 avec x de type objet
Page 18
BUT de la mutation (swizzling) de pointeur
• Éviter la consultation de tables en matérialisant l’adresse en RAM
Techniques de matérialisation des adresses :
1- En place/copie2- Tous/sur demande 3- Direct et indirect
Page 19
Techniques de rangement et de mutationserveur de pages
• Les objets sont rangés dans des pages de taille 4, 8, 16Ko• L’unité de transfert entre le disque et la RAM est la page• Sur demande d’une application le système détermine si l’objet
est en RAM avec le ORM ou si une page disque doit être transférée ( via le OP).
• Une page transférée est rangée dans un frame de la cache soit sur le serveur (serveur d’objets) soit sur le client (serveur de pages).
Page 20
Techniques de transfert des pages : en place
1- En placeLes pages transférées au client sont rangées dans la cache;
La mutation des pointeurs se fait en place initiale avec les objetsréférés.
En ré-écriture de la page, les pointeurs mutés doivent être dé-mutés (unswizzling) y compris ceux des objets non modifiés par une application.
Page 21
Techniques de transfert des objets : par copie
2- par copie• La mémoire RAM est divisée en deux partie: une partie pour
ranger la page et une 2e pour y loger progressivement une copie des objets référés (cache objets-référés).
• Seuls les objets référés font l’objet de la mutation (swizzling on demand).
• En ré-écriture sur le disque, seuls les objets modifiés font l’objet d’une dé-mutation des pointeurs ( partie objets référés).
Page 22
Mutation de pointeur directe/indirecte
• Directe : un pointeur est une adresse réelle de l’objet pointé. Tout déplacement d’objet référé ou de ré-écriture peut rendre caduque ces pointeurs.
• La démutation des pointeurs directs exige un pointeur inverse:
Objet référant
Objet référé
Page 23
Chargement immédiat/sur demande
• Immédiat: Lorsque que les objets sont chargés dans la cache, tous les objets référés le suivent.
• Sur demande: Les objets référés par un objet déjà chargé, sont aussi chargés que sur demande de l’application, c'est-à-dire au moment de la référence.
Page 24
Les version d’objet : fonctionnalité des SGBDOO
• Le versionnage conserve plusieurs générations modifiées (états) du même objet.
• Ce mécanisme permet de revenir en arrière et d'interroger les anciens états des objets à des dates précises ( BD temporelle).
Page 25
Les versions d’objet
• Exemples: les différentes versions d’un plan ou d’un texte en révision…
• Les versions sont conservées en totalité ou en image différentielle : seuls alors les ajouts ou les modifications à la version précédente sont stockés dans un espace spécialisé. Au besoin, la version est reconstituée par le SGBD.
Page 26
Constructeur de valeur et d’objet complexes : tuple
Valeur complexe: construite à partir des valeursatomiques et des constructeurs de types disponibles : ….alphanumériques incluant le type son, image, clip, …
Constructeurs de types complexes sont les suivants : tuple( ) :
Exemple: (type équivalent au record/vecteur)Type : tuple (nom : string, salaire : integer)Sa valeur: tuple (nom : "Pierre", salaire : 25000)
Page 27
Quelques constructeurs de type: SET(), List()
Ensemble homogène de valeurs:Types: ex. Set (number), unique set(int)Valeurs (constantes) complexes: ex.
set (3,6, 3, 9), unique set(3,6,9)Liste:Ensemble ordonné de valeurs homogènes (avec indexation 0)
Type List (number)valeurs de liste : list (3, 2, 3, 6) ou list( "A", "B", "C")Tuple :Ensemble non homogène de valeurs ( attribut valué)
Page 28
Spécification complète d’une classe O2avec leur visibilité respective
• Class Vol type(Tuple (
read nom: string,public tarif: real,read inscrits: list(Personne))
Methodpublic demandeReservation(nb : integer): boolean,Public modifierTarif(nouvTarif : real)End;
La classe Vol fait référence à une autre classe Personne qui peut ne pas être définie à ce moment (shadowing autorisé en O2).
Page 29
Visibilité dans une classe O2
• Class Vol type(Tuple ( read nom: string,
public tarif: real,read inscrits: list(Personne),private placesDispo integer )
Methodpublic demandeReservation(nb : integer): boolean,public modifierTarif(nouvTarif : real),private effectuerReservation(nom: Personne, qte: integer)End;
** la visibilité est gérée au niveau le plus fin, soit l’attribut et la méthode.
Page 30
Objet et valeur nommés (O2)
• O2 permet d’assigner un nom permanent et global à une valeur ou à un objet. Ces noms sont rangés dans le dictionnaire du SGBD et sontconnus par toutes les applications.
Objet nommé:Name B747 : Avion -- représente une instance particulière de la classe AvionName Canada : Pays; -représente une instance de Pays.
Valeur nommée:Name GrandeVille list (“Montreal”, “Toronto”, “Vancouver”)
Un objet et une valeur nommés sont persistants et globaux. Un telobjet est accessible par son nom sans déclaration dans une applicationpuisqu'un objet et une valeur nommés sont stockés dans le dictionnaire.
Page 31
Rangement des objets : extension (container)
• Les objets homogènes sont rangés généralement dans une structurede type ensemble d’éléments complexes (pas obligatoirement).
Name lesEmployes : set(Employe)
• La structure nommée lesEmployes est un ensemble d’objets de type Employe.
A chaque création d’objet, son insertion dans son extension (Insert deOracle) relève de l’application. Ce rangement rend l’objet persistant.
Page 32
Interfaces de programmation en O2
• Interface O2 API : spécifique et performance avec accès direct au moteur O2
• Interface C++ et C : ajout indirect de la persistance pour les structures propres à C++ et C
• Interface avec L4G : O2CRapide avec accès à toutes les fonctionnalités
Page 33
Caractéristiques du langage O2C
• Sur-ensemble de C (donc langage procédural et complet sur le plan computationnel).
• Permet la création d’objets.• Paradigme de l'envoi de messages: appel des méthodes.• Manipulation de données complexes dans le langage.• Exploite les méthodes stockées dans la base d’objets.
Page 34
Caractéristiques du langage OQL
Standard ODMG• Orienté SQL• Disponible en 2 modes : interactif et intégré dans un L3G.
– Interactif : Select e.salaireFrom e in lesEmployes (entension ou point d’entrée)
Where e.position = "Reporter " ;
Page 35
Propriétés de l’objet O2
• Chaque objet a une identité indépendante de sa valeur: Objet1 = [oid1, 45] Objet 2= [oid2, 45]
• La valeur d’un objet mise à jour sans changement de son identité.
• Identité et égalité deux concepts distincts: == et =• Les objets sont partageables.• Les objets peuvent être cycliques ou réflexifs.
Page 36
Évolution du schéma O2
• Ajout d’une classe et d’une signature (exige cependant la recompilation des applications utilisant ces modifications)
• Changement possible de visibilité: attribut et méthode
• Changement de la signature (liste de ses paramètres) d’une méthode
• Renommer une classe et un attribut
• Renommer un méthode dans une classe
Structure logique et schéma O2
• La structure logique d’une base O2 est définie pas son schéma nommé: Ex.: Create Schema Production;
• La base physique est créée à l’image du schéma par les commandes :
Set Schema Production;Create base BDProduction;
• La base renferme les objets, les programmes, …
Page 38
Partage d'un schéma entre les bases
Schéma Production
Base ProdJuinC
BaseProdJuillet
Create schema Production;Class Produit…;Class Equipe….;
Create base ProdJuin;Create base ProdJuillet;
Set schema Production ;Set base ProdJuin;
BDO-O2-héritage et interface © Page 39
Types atomiques de O2 et O2C
• Boolean TRUE, FALSE • Bits ''1001''• String ''tableau de Riopelle''• Char 'A'• Integer -200, 350• Real 45.78
• Instance d'un type : c'est une valeur avec une structure ou encore un objet sans oid.
BDO-O2-héritage et interface © Page 40
Types complexes construits (usagers) TAD : tuple()
• Constructeur du type tuple() avec référence réflexive et regroupant des attributs de type différent:
tuple( nom : string,age : integer,conjoint : Personne, -- absence de REFville : tuple ( nom: string, code : integer),pays : Pays)
Personne et Pays définis comme des classes.
Ce type peut être utilisé pour définir une classe. Une instance d'une classeest un objet. Notez l’absence de référence comme type (différence avec
Oracle).
Page 41
Classe définie avec le constructeur tuple()
• Définition d'une classe
Class Personne typetuple( nom : string,
age : integer,conjoint : Personne, ville : tuple ( nom: string, code : integer),pays : Pays)
End;
BDO-O2-héritage et interface ©
BDO-O2-héritage et interface © Page 42
Constructeur de type list()
• Collection ordonnée d'objets ou de valeurs de même type.
list( tuple( nom : string,famille : set (Personne))
)
Instance du type : une valeur de type liste:list(tuple(''Suzanne'', set(oidP1, oidP2), …))
Où oidP1 est un oid sur un objet Personne dont l’instance est :personne1.
BDO-O2-héritage et interface © Page 43
Création d'un nom de type: Create Type
Create Type infoClient_t: tuple( nom: string; prenom: string, rue);
En O2C: déclaration de var O2C:
o2 infoClient_t ic; …ic = tuple (nom: ''Denin''; prenom: ''Albert'', rue:''Laurier'');…
BDO-O2-héritage et interface © Page 44
Classe basée sur le type list()
class Population typelist( tuple( nom : string,
famille : set (Personne))
End;
Instance de Population :oid + list(tuple(''Suzanne'', Set(oidP1, oidP2),…))
Où oidP1 est le oid sur l'objet Personne P1.
BDO-O2-héritage et interface © Page 45
Opérations sur une liste
Name listA : list(); --création d'une liste nommée vide
• Affectation : listeA = list (1, 2)• Comparaison: IF (listeA == list(1, 2)) { }• Concaténation : listeA += liste(1,2)• listeA = listeB + list(3)• Accès direct : listeA[1] ou listeA[i]• Appartenance: rang = (2 in listeA) • Sous-liste : listeA[0:2] • Taille de liste: Count(listeA)• Remplacement : listeA[1] = list(9)
BDO-O2-héritage et interface © Page 46
Suite opérations sur list()
Avec : o2 list(integer) listeA = list();
• Insertion : listeA[4] += list(7) 7 est la valeur en position 4
• Effacement: listeA[0:3] = list() -- liste vide
• Itération : For x in listeA Where condition) { }
BDO-O2-héritage et interface © Page 47
Variables O2C
• Variables de O2C sont celles de C ou un type O2 atomique ou complexe
Exemples : o2 Population p;o2 Personne pers;o2 integer q, t, s;int w = 10; -- var. C
BDO-O2-héritage et interface © Page 48
Constructeurs d'ensemble avec doublon: Set()
• Un set peut avoir plusieurs fois la même valeur sauf pour Unique Set().
Class Ouvrier typetuple (nas : string,
nom : string,parents : set (Personne), salaires : list(real),photo : Bitmap)
MethodPublic AjoutSalaire(nouvSal : real) : booleanEnd;
BDO-O2-héritage et interface © Page 49
Opérations sur le SET()
• Affectation : setA = set(1) -- init • Comparaison: If (setA == set(1,2,3) ) { }• Union : setA = set(2) + set(3, 1)• Intersection : setA = setB * set(1, 2, 3, 4)• Difference : SetA = SetB - set(3)• Appartenance: varBool = ( x in SetB) ou (4 In SetB)• Taille : nb = Count(SetA)• Insertion d'un objet ou une valeur : setA += set(2)
BDO-O2-héritage et interface © Page 50
Opérations sur le set() suite
• Suppression: setA -= set(2)
• Itération: For ( x In setA Where condition) { }
La variable x du type des éléments de setA prend successivement la valeur des éléments du set.
Si la condition est vérifiée le bloc { } est exécutée et l'itération se poursuit sauf si présence d'un break.
BDO-O2-héritage et interface © Page 51
Type String ou Bits
• Mêmes opérations que celles sur les listes
o2 string r, s; -- déclaration de variables stringR = ''Hello''; -- ''Hello''S = R + R -- ''HelloHello''
R += S; -- ''HelloHelloHello''If S[2:4] == ''llo'' && Count(R) > 10) { }
BDO-O2-héritage et interface © Page 52
Implémentation de la méthode O2
• Un objet est caractérisé par sa classe • Une méthode est une fonction associée à une classe • La spécification d'une méthode est sa signature• Les arguments d'une méthode doivent avoir un type O2C:
demanderReservation (nb : integer) : boolean in class Vol
• Implémentation d'une méthode par le body:Method body demanderReservation (nb:integer): boolean in class Vol{….code O2C}
BDO-O2-héritage et interface © Page 53
Héritage en O2
• Class TrajetTrain type tuple(noT : integer,depart : Date,arrivee: Date),Method
calculerTarif: real End;
Class TrajetReduit INHERIT TrajetTraintype tuple( periode integer,
coefficientR : real)End;
TrajetTrainnoT: integerdepart: arrivee:
calculerTarif
TrajetReduitperiode: integer,coefficient: real
Avec la valeur nommée : name Tarif :list(real), liste initialisée avec les prix réguliers indexés avec le numéro du train (noT).
BDO-O2-héritage et interface © Page 54
Extension d'une hiérarchie de classes
• Les objets d'une superclasse avec ceux de toutes ses sous-classes peuvent être rangés dans la même extension. (principe de substitution des types ou de cohabitation des objets de Oracle);
• Le rangement des objets O2 est la responsabilité de chaque application.
• Une structure d'ensemble nommée est utilisée comme extension des objets
Ex. Name lesEmployes : list(Employe) ou set(Employe) --- pour stocker les objets de Employe
BDO-O2-héritage et interface © Page 55
Implémentation des méthodes (fonctions)
• Method body calculerTarif:real In class TrajetTrain{ return ( tarif[self->noT]); -- tarif[] est une liste nommée
-- Indicée par le no du train}
BDO-O2-héritage et interface © Page 56
Redéfinition des méthodes dans une sous-classe
• Method body calculerTarif:real In class TrajetReduit -- même signature
{ return ( Tarif[self->noT] * self->coefficient); }
La méthode calculTrarif est ainsi redéfinie dans la sous-classe.
BDO-O2-héritage et interface © Page 57
Redéfinition des méthodes : cohérence des signatures
• La redéfinition d'une méthode O2 exige une signature identique, définie ainsi: le nombre et le nom des paramètres doivent être les mêmes;
• Le type de chaque paramètre doit être le même ou être un sous-type du paramètre correspondant.
Exemples Employe étant une spécialisation de Personne :
Method reservationPlace (qui : Personne, qte: integer) : boolean IN CLASS Personne;
Method reservationPlace (qui : Personne, qte: integer) : boolean IN CLASS Employe;
BDO-O2-héritage et interface © Page 58
Héritage avec x sous-classes
Transport:dateT:DateplacesDispo: intInscrits: set(int)demanderReserv
Avion:noVol: inttarifmodifTarif
TrajetTrain:noT: intdepartarriveecalculTarif
Class Transport typetuple( dateT : Date,placesDispo : integer,inscrits : set( integer )MethoddemanderReserv (qte:integer)End;
Class Avion INHERIT Transport type tuple ( noVol: integer,tarif : real)End;
Class TrajetTrain….
Les classes sont toutes instanciables en O2; les notions de {c} et {i} sont à la charge de l'applicationqui peut ou doit les renforcer (lacune)
(c, i)
BDO-O2-héritage et interface © Page 59
Héritage multiple :conflits potentiels
Class Etudiant typetuple(mat : integer,
tauxH: integer),MethodcalculSalaire: realEnd;
Class Personne typetuple(nas: integer,
tauxH: integer),MethodcalculSalaire: realEnd;
Class MoniteurLabo typetuple(noContrat : integer, nbHeures: integer),MethodlireNbHeure:integerEnd;
BDO-O2-héritage et interface © Page 60
Conflit de nom : renommage automatique par le système
• Solution O2 : structure de la sous-classe sans prise en charge de l’héritage multiple:
Class MoniteurLabo typetuple(noContrat : integer,
nbHeures: integermat : integer,nas : integertauxH : integertauxH : integer),
MethodlireNbHeure:integer,calculSalaire: real,calculSalaire: realEnd;
BDO-O2-héritage et interface © Page 61
Résolution du conflit par le système : préfixage
Class MoniteurLabo typetuple(noContrat : integer,
nbHeures: integer,mat : integer,nas : integer,Etudiant_tauxH : integer,Etudiant_tauxH : integer)
MethodlireNbHeure:integer,Personne_calculSalaire: real,Etudiant_calculSalaire: realEnd;
BDO-O2-héritage et interface © Page 62
Conflit de nom : renommage par le DBA
• Ce renommage peut aussi se faire par le DBA:
Rename Attribute tauxH From class Etudiant As Etud_tauxH in class MoniteurLabo
Rename Method calculSalaire From class Personne As Method Pers_CalculSalaire in class MoniteurLabo.
BDO-O2-héritage et interface © Page 63
Héritage répété
Personnenom :string
Moniteur
assiste: set(Enseignant)
Etudiantsuit list(Cours)
horaires : list(Date)
Enseignantdonne: list(Cours),horaires : list(Date))
BDO-O2-héritage et interface © Page 64
Renommage de l'attribut
Class Moniteur inherit Enseignant, EtudiantRename attribute horaires from class Etudiant as Horaires_EtudiantTypel( tuple( assiste : set(Enseignant))End;
Structure de la classe Moniteur:type tuple( nom : string,donne list(Cours)horaires_Enseignant list(Date) /* a été renommé */assiste : set(Enseignant)
BDO-O2-héritage et interface © Page 65
Représentation des associations UML en O2
• Association 1..1 (Notez la définition symétrique de l'asso)
Class Pays typetuple( sorteGouv : string,Population : integer,aPourCapitale : Ville)End;
PayssorteGouv: population:int
VillenomVille:coordGIS
1..1 0..1< laCapitale
Class Ville typetuple( nomVille : string,coordGIS : integer,laCapitale : Pays)End;
Règle de validation: l'attribut laCapitale peut avoir un objet null.La validation sera à la charge des méthodes.
BDO-O2-héritage et interface © Page 66
Représentation de l'association 1..*
Class Usine type tuple( noU : integer,villeU: string),comprend : set(Atelier)),MethodgetVille: stringEnd;
Class Atelier type tuple( noA : integer,chef: string),nbOuvriers : integer,travaillePour : Usine),MethodajoutOuvrier(nb:integer)End;
Règle de validation : comprend ne peut pas avoir un set vide comme valeurRègle de validation différente si 0..1
UsinenoU:villeUgetUsine
AteliernoA:chefnbOuvriers
1..1 1..*Comprend >
BDO-O2-héritage et interface © Page 67
Représentation de l'association 1..* - 1.. *
Class Usine type tuple( noU : integer,villeU: string),sousTraite: set(Atelier))MethodgetUsine: stringEnd;
Class Atelier type tuple( noA : integer,chef: string),nbOuvriers : integer,travaillePour: set(Usine))MethodajoutOuvrier(nb:integer)End;
Règle de validation: les 2 set() ne peuvent pas être videsValidation assurée par les méthodes certifiées par le DBA
UsinenoUvilleUgetUsine
AteliernoAchefnbOuvriersajoutOuvrier( )
1..* 1..*sousTraite>
BDO-O2-héritage et interface © Page 68
Association réflexive
Class Personne type tuple (nas : string,nom : string,dateNaiss : Date,mere : set(Personne),enfantDe: Personne)
End;
Personnenas : stringnom :dateNaiss:
mere
enfantDe1..1
1..*
Règle de validation : le set de l'attribut mere ne peut pas être vide et la valeur de EnfantDe ne peut pas être un objet null.
BDO-O2-héritage et interface © Page 69
Liaison dynamique
C'est la nature de l'objet appelant qui détermine la méthode exécutée.
o2 TrajetTrain t;o2 TrajetReduit tr;o2 real x, y, z;… création et initialisation du trajett = tuple (noT: 50, depart: ''12-4-2003'', arrivee: ''13-4-2003'')tr = tuple (150,depart: 12-4-2003, arrivee: 13-4-2003)
x = t->calculerTarif; /* tarif normal */y = tr->calculerTarif; /* tarif réduit */t = tr; /* le trajet est maintenant celui réduit */
BDO-O2-héritage et interface © Page 70
Liaison dynamique dans la fouille d'une liste
L'objet appelant détermine son comportement.
o2 list(TrajetTrain) circuit;o2 TrajetTrain t;o2 real tarif;o2 TrajetTrain ta, tb;o2 TrajetReduit tr1, tr2, tr3;…circuit = list (ta, tr1, tr2, tb, tr3);FOR ( t IN circuit) tarif += t->calculerTarif; ….
BDO-O2-héritage et interface © Page 71
Liaison statique avec une méthode
• La méthode de la classe parent est appliquée même si elle est redéfinie dans la sous-classe
• L'objet self est de type TrainReduit
Method body calculerTarif IN Class TrajetReduit{o2 real x;x = self->TrajetTrain@calculerTarif; méthode imposéeReturn ( x * self->coefficient);}
BDO-O2-héritage et interface © Page 72
Exemple : Billetterie de gare
Le gestionnaire d'une gare ferroviaire veut avoir des statistiques sur les deux sortes de billets vendus au comptoir: billet pour un train régulier et celui pour un train rapide. Le prix de base pour un billet est fixé à 0.50 le kilomètre selon la distance entre la gare de départ et celle d'arrivée. Pour tout trajet inférieur à 50 km, le prix est fixé à 25.00.
Le prix du billet pour les trains rapides en direction de Vancouver est majoré d'un supplément de 10% par rapport au prix de base. Le billet pour un train rapide est aussi majoré par un coût de restauration spécifique à chaque parcours.
Un utilisateur peut bénéficier d'une réduction entre 10 et 20% et qui ne peut s'appliquer que pour des trains réguliers. Tous les attributs sont privés et les méthodes publiques. Lorsqu'un billet est créé, il est rendu immédiatement persistant. Faites appel au binding statique pour éviter de dupliquer le code.
BDO-O2-héritage et interface © Page 73
Billetterie de gare (suite)
1. Donnez le diagramme de classe de cette base comprenant une spécialisation;
2. Donnez le schéma correspondant à ce petit scénario qui comprend que trois classes.
3. Créer les extensions appropriées;4. Coder le code init() des classes du schéma : initialisation et
persistance5. Code la méthode tarif pour chaque classe.
BDO-O2-héritage et interface © Page 74
Diagramme de classe (UML) et schéma
Billetkilo : integergareD : stringgareA : stringdate : Date
BilletRegreduction: integer
BilletRapsupp: integer
resto: real
class Billet private type tuple(kilo : integer, gareD : string,gareA : string,date : Date) -- date du train
method public tarif: realEnd;
class BilletReg inherit Billettype tuple(reduction : integer) -- 1 pour sans réduction
method public tarif : real,public init(kilo:integer, gareD : string, gareA : string, date : Date, reduction : integer)End;
class BilletRap inherit Billettype tuple(supp: integer,resto : real)
method public tarif: real,public init(kilo:integer, gareD : string, gareA : string, date :Date, supp : integer, resto: real)End;
{c, d}
Redéfinition de la méthode Init dans chaque classe
BDO-O2-héritage et interface © Page 75
Les extensions
• La classe Billet ( classe abstraite UML) n'a pas d'extension en raison de la spécialisation {c, d}.
Les seules extensions créées pour cette base :
name lesBilletRegs : set(BilletReg);
name lesBilletRaps : set(BilletRap);
La classification disjointe des billets est concrétisée par les deux extensions.
BDO-O2-héritage et interface © Page 76
Méthode Init() de BilletReg
method body Init (kilo :integer, gareD : string, gareA string, date : Date, reduction :integer) in class BilletReg
{self->kilo = kilo; -- attributs hérités
self->gareD = gareD; -- attributs hérités
self->gareA = gareA; -- attributs hérités
self->date = date; -- attributs hérités
self->reduction : integer; -- attribut spécifique
[lesBilletRegs += set(self);] – au besoin objet init et persistant
};
BDO-O2-héritage et interface © Page 77
Init() de BilletRap
method body Init (kilo :integer, gareD : string, gareA string, date: Date, supp :integer, resto: real) in class BilletRap
{self->kilo = kilo; -- attributs héritésself->gareD = gareD; -- attributs héritésself->gareA = gareA; -- attributs héritésself->date = date -- attributs hérités. Date du trainself->supp = supp; -- attribut spécifiqueself-> resto = resto; -- attribut spécifique[lesBilletRaps += set(self);] --objet init et rendu persistant au besoin
};
BDO-O2-héritage et interface © Page 78
Méthode tarif de Billet
method body tarif :real in class Billet{o2 real x;IF (self->kilo < 50) x = 25.00;
Else x = self->kilo * 0.50;return x;}
BDO-O2-héritage et interface © Page 79
Méthode tarif du Billet Reg
method body tarif: real in class BilletReg{o2 real x;x = self->Billet@tarif * self->reduction; -- binding stat.return x; };
Liaison statique
BDO-O2-héritage et interface © Page 80
Méthode tarif de BilletRap
method body tarif: real in class BilletRap{o2 real x;x = self->Billet@tarif * 1.10 + (self->resto);return x;};
Liaison statique
Langage O2SQL
BDO-O2-héritage et interface © Page 81
BDO-O2-héritage et interface © Page 82
Requêtes O2SQL sur la base Billetterie
• Quelles sont les gares d'arrivée pour lesquelles il y a eu émission d'un billet pour un train régulier?
Select b->gareAFrom b in lesBilletRegs;
• Combien de billetS à tarif régulier ont été vendus?Count(lesBilletRegs); -- une fonction sur un ensemble
• Combien billets réguliers ont été émis pour un parcours de moins de 250 kilomètres?Count( Select x From x in lesBilletRegs Where b->kilo <250)
BDO-O2-héritage et interface © Page 83
Requêtes O2SQL (suite)
• Quelles gares d'arrivée distinctes ont été inscrites dans l'émission des tickets à train rapide?
Select Distinct b->gareAFrom b in lesBilletRaps;
• Quelles gares d'arrivée ont été inscrites dans les billets et cela pour un train rapide au mois de novembre?
Select Distinct b->gareAFrom b In lesBilletRapWhere b->date->get_month = 11;
BDO-O2-héritage et interface © Page 84
Requêtes O2SQL (suite)
• Quels sont les taux de réduction consentis pour les départs de la gare de Québec?
Select Distinct x->reductionFrom x IN lesBilletRegWhere b->gareD = ''Québec'';
• Affichez les gares de départ qui ne sont pas aussi des gares d'arrivée pour les billets réguliers pour les trains après 2002?
(Select Distinct x->gareDFrom x IN lesBilletRegs Where x->get_year > 2002)
Except (minus)(Select Distinct x->gareAFrom x IN lesBilletRegs Where x->get_year > 2002);
BDO-O2-héritage et interface © Page 85
Requêtes O2SQL (suite)
• Trouvez les gares de départ dont le nom contient la chaîne ''le ''.(Select Distinct g->nomFrom g in lesBilletRegWhere g->gareD like ''*le*'')UNION(Select Distinct g->nomFrom g in lesBilletRapsWhere g->gareD like ''*le*'');
BDO-O2-héritage et interface © Page 86
Requêtes O2SQL imbriquées dans O2C
Formulez un programme O2C avec la fonction o2query pourtrouvez les gares de départ dont le nom contient la chaîne ''le ''.
** Importance de connaître à priori le type du résultat afin de déclarer une variablede type approprié. **
Run body{o2 set(string) noms;o2query ( noms, '' (Select g->nom
From g in lesBilletRegWhere g->gareD like ''*le*'')UNION(Select g->nomFrom g in lesBilletRapsWhere g->gareD like ''*le*'') ;
Display (noms);};
BDO-O2-héritage et interface © Page 87
Autres cas de spécialisation
BDO-O2-héritage et interface © Page 88
Schéma et la spécialisation {i, d} et 3 extensions
• Voici une spécialisation partielle et disjointe {i,d}PersonnenasPnomPdateNaiss
Employe depEnomSynd
EtudiantematEnoD
Class Personne Private type tuple(nasP : integer,
public nomP : string,dateNaiss : Date)End;
Class Etudiante inherit Personne Private type tuple(matE : integer,
noD : integer)End;
Class Employe inherit Personne Private typeTuple( depE : string,nomSynd : string)End;
name Personne : set(lesPersonnes)name Etudiante : set(Etudiante);name Employe : set (Employe);
{i, d}
Le incomplete de la spécialisation est rendu par la création d'une extension séparée. A la création d'un objet, l'application a l'obligation de l'insérer dans l'extension appropriée.
BDO-O2-héritage et interface © Page 89
Spécialisation {i, d} avec une seule extension
Pour y arriver il faut ajouter un attribut prédicatif : son évaluation par un prédicatdétermine la sorte d'objet. Une seule extension suffit pour le rangement des objets.
PersonnenasPnomPdateNaisssorte
Employe depEnomSynd
Etudiant(e)matEnoD
Class Personne private type tuple(nasP : integer,
public nomP : string,dateNaiss : Date,sorte : integer)End;
Class Etudiante inherit Personne Private type tuple(matE : integer,
noD : integer)End;
Class Employe inherit Personne private typeTuple( depE : string,nomSynd : string)End;
name Personne : set(lesPersonnes)
{i, d}
Le incomplete de la spécialisation est alors rendu par la valeur de l'attribut sorte : 1 pour une personne autre qu'une étudiant(e) et un employé, 2 pour une étudiant(e) et 3 pour un employé.
A la création d'un objet, il est ajouté dans l'extension lesPersonnes qui regroupe tous les objets.
BDO-O2-héritage et interface © Page 90
Spécialisation {i, o} avec une seule extension
Pour y arriver il faut aussi ajouter un attribut prédicatif : son évaluation par un prédicat détermine la sorte de l'objet. Une seule extension suffit pour le rangement des objets.
Class Personne private type tuple(nasP : integer,
public nomP : string,dateNaiss : Date,sorte : integer)End;
Class Etudiante inherit Personne private type tuple(matE : integer,
noD : integer)End;
Class Employe inherit Personne private typetuple( depE : string,nomSynd : string)End;
name Personne : set(lesPersonnes)
Le incomplete de la spécialisation est alors rendu par la valeur de l'attribut sorte : 1 pour une personne autre qu'une étudiant(e) et un employé, 2 pour une étudiant(e) et 3 pour un employé. Le overlapping n'est pas l'objet d'une gestion particulière et il y aura une redondance des données.
A la création d'un objet, il est ajouté dans l'extension lesPersonnes qui regroupe tous les objets. Si une personne est à la fois étudiante et employée, alors deux objets sont créés et il y aura redondance pour certains attributs communs.
PersonnenasPnomPdateNaisssorte
Employe depEnomSynd
Etudiant(e)matEnoD
{i, o}
BDO-O2-héritage et interface © Page 91
Comment éviter cette redondance avec un héritage {i,o} Modélisation sans spécialisation
Une personne est à la fois employée et étudiante. La spécialisation estremplacée par deux associations (un sens seulement).
FichePersonnenasPnomPdateNaiss
Employe depEnomSynd
Etudiant(e)matEnoD
fichePersEmplfichePersEtud
11
1 1
Class FichePersonne type tuple(nasP : integernomP : stringdateNaiss : Date)End;
Class Etudiant type tuple (matE : integernoD : integerFichePersEtud : FichePersonne)End;
Class Employe type tuple(depE : integernomSynd : stringFichePersEmpl : FichePersonne)End;
Une personne à la fois employée et étudiante partagera le même objet FichePersonne. Toute modification à cet objet FichePersonne est visible et partagée par les objets de Etudiant et Employe.
BDO-O2-héritage et interface © Page 92
Schéma et méthodes de la BDO ClientèleScolaireassociation complexe avec classe-association
Elevematricule : integernom : stringprenom : stringdateNaiss : DateDiplomes: list(string)
EleveSececole : string filiere : integer
Collegiencegep : integerformation : string
{c, d}
CoursMathnoCours : integertrimestre : string
0..*
1..*
InscritCMnoteCM
class Eleve private type tuple ( matricule : integer, nom : string, prenom : string,diplomes : list (string))
method afficherEleve, -- private par défautajoutDiplome(d: string), -- private par défautafficherEleve end;
class EleveSec INHERIT Eleve <-- lien d'héritagepublic type tuple (ecole : stringFiliere: integer) -- 1 pour courte et 2 pour longue
public method modifFiliere -- + méthodes héritéesend;
class Collegien INHERIT Elevetype tuple (cegep: string, formation : stringinscritCM :set( tuple (CM: CoursMath, noteCM: real)))
public method diplomer()end;
BDO-O2-héritage et interface © Page 93
Agrégation de composition et de partage
BDO-O2-héritage et interface © Page 94
Agrégation de composition en BDOO : une association spéciale
Livre auteur :string titre : stringanPubl : Date
PhotonoPho pagePho
0..*
Agrégation de composition : la suppression d'un livre entraîne celle des photos de ce livre. Cependant l'ajout d'une photo dans la BD peut se faire sans avoir immédiatement une association avec un livre.
Les extensions: name lesLivres : set(Livre)name lesPhotos : set(Photo)Agégation de composition:class Livre type tuple (
auteur : string,titre : string,anPubl : Datecomprend : set(Photo))
methodsuppLivre :booleanEnd;
class Photo type tuple (noPho : integer,pagePho : integer)
methodsuppPhoto : BooleanEnd;
Pour une composition: la méthode suppLivre appelle la méthode suppPhoto pour supprimer la photo.
BDO-O2-héritage et interface © Page 95
Agrégation de partage en BDOO : une association spéciale
Livre auteur :string titre : stringanPubl : Date
PhotonoPho pagePho
0..*
Agrégation de partage : la suppression d'un livre n'entraîne pas nécessairement celle des photos de ce livre. L'ajout d'une photo dans la BD peut se faire sans avoir immédiatement une association avec un livre.
Les extensions: name lesLivres : set(Livre)name lesPhotos : set(Photo)
class Livre type tuple (auteur : string,titre : string,anPubl : Datecomprend : set(Photo))
methodsuppLivre :booleanEnd;
class Photo type tuple (noPho : integer,pagePho : integer)
methodsuppPhoto : BooleanEnd;
Pour l'agrégation de partage, la méthode SuppLivre se limite à supprimer l'objet livre.
BDO-O2-héritage et interface © Page 96
Méthode suppLivre (agrégation de composition)
• Method body suppLivre: boolean in class Livre {o2 Photo p;o2 Livre l;For ( p IN self->comprend) {p->suppPhoto; lesLivres -= set(self);
return True;}Else return False;};
Method body suppPhoto in class Photo{ lesPhotos -= self;}};
BDO-O2-héritage et interface © Page 97
Méthode suppPhoto (agrégation de partage)
• Method body suppLivre: boolean in class Livre {o2 Photo p;o2 Livre l;For ( p IN self->comprend) {lesLivres -= set(self); return True;}Else return False;};
Page 98
Structure générale du langage O2C
• Langage sur-ensemble du C • Un programme en O2C est défini par : { ….}• Objet et valeur présents dans O2C• Section déclaration des variables préfixées avec "o2"• Code de la logique du traitement :
– Itération– Alternative – Affichage– …
Page 99
Extensibilité de O2 avec O2C
• Au cours du développement (la BD vide), les opérations ci-dessous sont permises:
– Ajout, suppression d’une classe;– Ajout, suppression d’un attribut;– Rendre un objet persistant (par le code qui l’insère dans son extension);
– Changer la visibilité d’un attribut ;– Ajouter et supprimer une méthode;– Modifier une signature;– Mais : les propriétés de l’héritage sont simulées;(implémentées) par
les applications: {c,d}, {c,o}, {i,d}, {i,o}.
Page 100
Création d’objet dans O2C
• Opérateur NEW avec initialisation par défaut : créé un oid déterminé et une valeur ou objet nul.
O2 Personne x ;x = New Personne;…
• L’opérateur NEW appelle implicitement la méthode Init() de la classe. La méthode Init() n’est pas héritée :
x = New Personne ('Lucie", 28, … );
• Init initialise l’objet et le body de Init() peut-être redéfini.
Page 101
Redéfinition de la méthode Init()
• Pour chaque classe, la méthode init() est non héritable, mais elle estredéfinissable dans la classe.
method body Init ( nom: string, age: integer) in class Personne{self->nom= nom;self->age = age;[lesPersonnes += set(self);] -- possible : l’objet créé rendu persistant
}
New Personne ( "Dubois", 35);…Objet créé, initialisé par Init(). Sinon les valeurs des attributs de l’objet sont à null.
Page 102
Définition des valeurs en O2C via le type
Une valeur est une instance de type (sans oid et sans méthode).Son type O2C est préfixé par O2:
• Boolean:Déclaration : o2 boolean : marie;marie = True; ou marie = False;
• Caractère Déclaration : o2 char(1) sexe;sexe = 'F'; sexe = 'M'; (le caractère entre apostrophes)
Page 103
Valeurs numériques
• Entier (sur 2 octets)Déclaration:
{o2 integer : integer;age = 25;…
• Réel ( sur 4 et 8 octets)Déclaration :
{o2 real: total ;total = 554.34;…
Page 104
Chaîne
• Chaîne de caractères :Déclaration :
o2 string: nomFamille;nomFamille = "Tremblay"; Strcpy(nomFamille, "Tremblay");
…• Chaîne de bits :
o2 bits: cleSecurite ;cleSecurite = "100010001111011010101";…
Page 105
Valeur complexe hétérogène
• tuple():o2 tuple ( a: integer, nom : string, c: real);tuple ( a: 5, nom : "Margie", c: 4589.35);
Affectation d’une valeur complexe à une variable du type:
o2 tuple ( a: integer, nom : string, c: real) v;v = tuple ( a: 5, nom : "Margie", c : 4589.35);v.nom = "Denis"; …
Page 106
Valeur complexe homogène : collection
Set : collection non ordonnée de valeurs homogènes ou d’objets (bag).Bag : collection non ordonnée d'objets
Ajout dans une collection:
Déclaration:o2 set (real) salaires;salaires = set (2345.50, 4500.00, 5500.00); valeur d’ensemble
o2 set(Personne) groupe;o2 Personne p1, p2 ;p1 = New Personne ( );p2 = New Personne ( );groupe = set (p1, p2); ajout de deux personnes au groupe
…
Page 107
Collection sans doublet
• Ensemble d’éléments uniquesDéclaration:{o2 unique set (integer) lot2, lot3;o2 set(integer) lot1, lot5; -- aussi appelé un baglot1 = set ( 1, 2, 3, 3, 5);lot2 = set( 1, 2, 3, 5);lot2 = lot1; -- erreur de typelot5 = set ( 1, 2, 3, 3, 5);…}
Conversion par un Cast() explicite : ( type cible)lot5 = (o2 Set(integer)) lot2;
Page 108
Collection ordonnée
• Liste d’éléments (valeurs ou objets) homogènes ordonnés avec indexation 0
Chaque élément de la liste est référé (indexé) par son rang.Déclaration:
o2 list(integer) lint1, lint2;o2 list(Personne); o2 integer vint;lint1 = list( 1, 2, 2, 3, 4, 5);lint2 = list( 5, 2, 2, 4, 3, 1);IF (lint1 == lint2) { } -- True…
lint1 et lint2 sont deux listes distinctes par le rang des entiers.
Page 109
Parcours d’un ensemble d’objets
Itération dans un ensemble d'objets
Name lesEmployes : set(Employe); -- extension de la classe Employe
o2 Employe q;. . .For (q in lesEmployes) { instructions }
L'ensemble est entièrement parcouru sauf si présence d'un break dans le bloc vrai.
Page 110
Accès aux valeurs d’un objet : => ou .
• Définition de la classe Personne• Class Personne public type tuple( nom: string,
age : integer;photo : Bitmap;conjoint : Personneenfants : list(Personne)) end;
Accès aux valeurs de l’objet par le dot ou la flèche:{o2 Personne p; o2 integer a;p = new Personne( "Savoie", 36, …..);a = p.age; ou a= p->age;…
La liste est composée avec l’oid des objets
L’objet est représenté par son oid
Page 111
Accès dangereux aux valeurs d’un objet
• Désencapsulation de l’objet pour accéder à une valeur d’objet sans passer par une méthode:
{… --les attributs de Personne sont privéso2 integer a;o2 Personne p;a = (*p).age;et*p.age = 35;}
Contourne la définition d’une méthode pour la lecture d’une valeur.
Page 112
Accès à une valeur complexe
{ o2 tuple(nas: string, age: integer) vp;o2 Personne p = new Personne; -- objet nullvp.age = 21; -- accès par notation pointée ( dot notation)
p->age = 21; --accès à une valeur de l’objet par notation fléchée
vp = *p; -- accès et copie des valeurs de la structure de Personne p->age += 1;vp.age = 21; -- p->age vaut 22 et vp.age vaut 21}
Page 113
Partage d’un objet
Si un objet est partagé par plusieurs autres objets, une modification surl’objet est visible par tous les objets.{o2 Groupe manif = new Groupe (set()); -- classe Groupe définie comme un set
o2 Troupe demo = new Troupe (list());o2 Personne p, p1p = new Personne;p->nom = "Dubois"; p->age = 25;manif += set(p); -- ajout de la personne p dans le groupe
demo += list(p); -- ajout de la personne p dans la troupe
For (p1 IN Groupe) p1->age += 1; --age de Dubois est 26
For (p1 IN Troupe) x->age += 1; --age de Dubois est 27 (26 +1)
… -- objet p pour Dubois est partagé
Page 114
Manipulation des chaînes en O2
• Le string de O2, le array de C ont quelques propriétés différentes :– Une variable string 02C peut être un argument de toute fonction ssi la
fonction ne modifie pas la chaîne passée en argument.– Variable O2C ne peut pas être utilisée avec fg() et gets(), car l'argument est
modifiée par l'affectation de la lecture
Modification d'une chaîne O2 :{o2 string ville;char nom[50];strcpy(nom, "Beauport"); --aussi avec strcmp() et strlen()strcpy(ville, nom);. . .}
--->> String O2 s'utilise comme un vecteur de caractères :
Page 115
Copie de valeurs
{o2 list(integer) comptes;o2 integer prix, x;Int c; --var. du langage Cprix = 100;comptes = list(prix, 200);For ( x in comptes) Display (x);}
Display () est une fonction de O2C pour afficher des valeurs et non lesobjets.
Page 116
Méthodes prédéfinies
• La classe générique OBJECTdu système O2 a de nombreuses méthodes prédéfinies:
De copie : copy() et deep_copy()De comparaison : equal() et deep_equal()D’affichage : display et edit
deep_equal() compare en profondeur :
Si la comparaison atteint un attribut objet, elle se poursuit sur lavaleur de cet objet.
Page 117
Examen des valeurs en profondeur et en surface
Voici une base d’objets :oid1: list(oid2, oid2, oid3) oid4 : list(oid5, oid5, oid6) oid7: list ( oid8, oid9, oid10)oid2 : tuple(x: 3, y: 2)oid3 : tuple(x: 5, y: 7)oid5 : tuple( x: 3, y: 2)oid6 : tuple( x: 5, y: 7)oid8 : tuple (x:3, y: 2)oid9 : tuple( x:3, y: 2)oid10 : tuple(x: 5, y:7)
deep_equal(oid1, oid4) est True
equal (oid8, oid10) est True
Page 118
Copie profonde d’un objet
• deep_copy Méthode retournant un autre objet: oid différent , mais de mêmevaleur.
{o2 Personne p, q, r, s, t;p = new Personne; -- objet null et non persistantp-> nom = "Gaugin";p->age = 25;p-> enfants= list(r, s, t);q = (o2 Personne) p->deep_copy;}
q est une copie objet (non persistant) de p avec une liste d’objets pourenfants différents de ceux de p (nouveaux oids), mais avec la mêmevaleur.
Page 119
Copie de surface d’un objet
• Copy{o2 Personne p, q, r, s, t;p = new Personne; -- objet null avec enfants, attribut de set().p-> nom = "Gaudin";p->age = 25;p->enfants = list(r, s, t);q = (o2 Personne) p->copy;}
L’objet q est créé avec les mêmes valeurs que ceux de p, et les objets deenfants sont les mêmes.
Page 120
Égalité de deux objets p et q
• equal() retourne TRUE si les deux objets sont égaux en surface.p: (oid:2, nom: ‘A’, enfants: list(oid5, oid6)) ;
{o2 Personne p, q, r;q = (o2 Personne) p->copy; -- q: (oid:3, nom: ‘A’, enfants: list(oid5, oid6)) ;
r = (o2 Personne) p -> deep_copy; q: (oid:4, nom: ‘A’, enfants: list(oid7, oid8)) ;
IF ( p->equal(q) {….} -- True
IF (p->deep_equal(r)); { …} -- False
};
Page 121
Méthodes d’affichage
• Display
{o2 Vol v;v->display; -- affiche l’objet via O2Look sous forme non éditable.v->edit; -- affiche l’objet via O2Look sous forme éditable.}
Edition d’un objet présenté graphiquement par l’interface graphiqueO2Look:
Avec un clic sur le crayon, la valeur de l’objet est modifiée.
Page 122
Lecture
• Input
Fonction pour afficher un masque de saisie:
{…Input(Vol); -- masque de saisie des attributs de Vol…}
Page 123
Exécution d’un body
• Programme non nommé, compilé et exécuté
• Exemple: class Client public type (tuple(nom : string, noDossier : integer) End;
Run body {o2 Client p;p = new Client;p->edit; -- init de pIF ( p->noDossier > 350)
display( p->nom);};
Page 124
Définition de méthode O2 (body O2C)
Class Personne inherit Object -- ce lien d’héritage est aussi impliciteprivate type tuple(nas : int,
nom : tuple (nomF: string, prenom:string),dateNais : Date,conjoint : Personne,enfants : list(Personne),adresse : Adresse)
End;
Création de l’extension de la classe Personne :valeur nommée (persistante)
Name lesPersonnes: set (Personne)
Changement de visibilité de la classe Personne : le type du tuple devient publicpublic type in class Personne
Page 125
Ajout d’un objet par programme O2C
Dans un shell de O2C :Run body {o2 Personne p = new Personne; -- objet vide non persistantp->nas = 4500;p->nom.nomF = "Beaumont";p->nom.prenon = ‘Patricia’;p-> dateNais = new Date (30, 11, 1955);p-> adresse = new Adressep->adresse->rue = "Rene-Levesque";p->adresse->ville = ‘Québec’;p->adresse->pays = "Canada";q-> new Personne; -- objet videq->nom.nomF = "Tirion";q->conjoint = q;lesPersonnes += set(p); -- ajout d’objet dans l’extension => devient persistantp->edit;} -- objet ajouté avec son conjoint
p = tuple( nas : 4500, tuple(nom ; "Beaumont", prenom : "Patricia"), dataNais : (10, 11, 1955), conjoint: nil, enfants : list(), adresse : nil));
Page 126
Ajout d’une méthode à la classe Personne
Ajout d’un enfant à un parent. La méthode ajoutEnf est appelée par un objetPersonne correspondant au parent. Les attributs de Personne sont privés.
method public ajoutEnf ( nas: int, prenom : string) : Personne In class Personne
method body ajoutEnf (nas: int, prenom : string) in class Personne{o2 Personne c = new Personne;c->nas= nas;c->nom.nomF = self->nom.nomF; c->adresse = self->adresse;self->enfants += list(c);IF (self->conjoint ! = nil) { self->conjoint->enfants += list(c); }Return c; -- objet enfant retourné par la fonction}
Page 127
Ajout de la méthode mariage
method private mariage(nas: int, prenom: string, nomF : string) : Personne in class Personne
{o2 Personne pm = new Personne; -- creation du conjoint de l’appelantpm->nas = nas;pm ->nom.momF = nomF; -- initialisation de l’objet appelantpm ->nom.prenom = prenom;pm->adresse = self->adresse; self->conjoint = pm;pm->conjoint = self;lesMenages += set(pm);return pm;};
Page 128
Méthode de recherche d’un objet dans une extension
Recherche si une personne a des enfants en parcourant l’extension:Name lesPersonnes: set (Personne)
method private rechercheEnfant (nas : int): int in class Personne{ o2 Personne p, x;nb int; - - var. C et non O2C car absence du préfixeFor (x in lesPersonnes Where x->nas = self->nas And x->enfants != set() )
{ nb = count(x->enfants);}return nb; }
Page 129
Suppression d’un objet dans set()
• La suppression d’un objet se fait dans son extension, le rendant ainsi non persistant
Name lesPersonnes: set (Personne)Application:
{o2 Personne p new Personne (… ); initialisation de l’objet po2 Personne x;nb int;p->nas = 12;For ( x IN lesPersonnes Where x->nas = p->nas)
{lesPersonnes -= set(x);}nb = count(lesPersonnes);printf ….} ; -- l’objet x n’est plus persistant
Page 130
Suppression d’un objet dans list()
• La suppression d’un objet se fait dans son extensionName lesPersonnes: list (Personne) --peu pratique cependant!
Application:{o2 Personne p new Personne (… ); -- initialisation de p
int r, nb;p->nas = 12;r = (p In lesPersonnes); -- retourne le rang de p dans l’extension de type list
lesPersonnes -= lesPersonnes[r]; -- suppression de l’objet de rang r dans -- l’extension lesPersonnes
nb = count(lesPersonnes);printf ….} ;
Page 131
Complément sur la persistance
• Chaque objet nommé est persistant name Dupont : Personne;name circuit : list(Vol);name tarif : set (tuple (indice: integer, prix: real));
• Tout objet créé n’est pas persistant de facto;• Un objet créé et inséré dans son extension devient persistant;• Un objet non persistant qui est référé par un objet persistant devient
alors persistant;• Une racine de persistance est définie comme:
– une classe,– un objet nommé– une valeur nommée ayant un ensemble d’objets
Page 132
Indexation : mécanisme d’accès rapide aux objets
• Indexation d’une collections nommée d’objets ou de valeurs :• Les collections d’objets (les extensions) et les collections de
valeurs sont indexées sur – Un attribut atomique– Un attribut référençant un objet– Un attribut de collection
Exemples: Index lesPersonnes ON nasIndex lesPersonnes On enfants.nas
Page 133
fin
PS :Un programme O2C est développé comme un sur-ensemble de C.
Donc les instructions de C peuvent y être insérées, notamment les IF, WHILE et les Entrées/Sorties.
Page 134
Supplément à O2C
Page 135
Classe Date et ses méthodes
method body planif in class gestion{o2 Atelier a;o2 Date d, f;int y; -- var C...a = new Atelier;d = new Date( 3, 5, 2003); /* jour, mois, année */y = d->get_year; -- fournit 2003y = y + 1;...d->set_year(y); -- initialise année à 2004a->annee = d; -- année de création de l’atelierf->set_to_current_date; /* date du jour pour l’objet f */...lesAteliers += set(a); -- persistance de a}
Page 136
Partage d’un objet sans duplication
{o2 set (Ouvrier) q; -- var. de valeuro2 list (Ouvrier) x, y ;o2 Ouvrier o1, o2, y, x ; -- var. objet avec o1 partagé par x et qo1 = new Ouvrier;
o1->nom = "Gagnon"; o1->age = 22;o1 -> matricule = 1234;
x += list(o1); -- oid de gagnon ajouté à la liste de xq += set(o1); /*oid de Gagnon ajouté à l’ensemble q
Partage de l’objet Gagnon entre x et q */For (y in q where y->matricule == 1234) {y-> age +=1};
/* âge de Gagnon est maintenant 23 */For (y in x where y->matricule == 1234) {y -> age += 1};
/* le nouvel âge de Gagnon est 24 */lesOuvriers = += set(o1); -- o1 est rendu persistant}
Page 137
Affichage de la valeur des objets
Affichage de la valeur de tous les objets d’une extension
name lesEleves : set (Eleve)Application:
{ o2 Eleve x;For ( x in lesEleves) {display (*x); -- affichage avec la fonction
x->display; } -- affichage avec la méthode
}
• Désencapsulation de l’objet pour afficher la valeur !!
• Une autre façon? Au moyen de la création d’une variable tuple de structure similaire à l’objet, suivi d’affectation avec les attributs de l’objet
Page 138
Traitement des chaînes
- Longueur d'une chaîne de caractèresApplication:
{o2 string nom = "Polidus"; -- affectation d'une chaîneint l;l = count(nom); /*longueur de la chaîne, 7 sans le \0 */;Printf (…, I)
}
Page 139
Comparaison de deux chaînes
Run body{int l;o2 string m1, m2;. . .m2 = "chaine de 23 caractères " ;m1 = "chaine avec 25 caractères " ;IF (m1 == m2) printf ( .....); -- idem à strcmp(m1, m2) = 0
IF (m1 != m2 ) printf (. . . ); -- idem à strcmp(m1, m2) != 0
m1 += m2; /* m1 = m1 + m2 concat. de m1 et m2 */
l = count(m1);printf("longueur de la chaine %d \n", l ); -- 25 car.
}
Page 140
Attention : manipulation des chaînes en O2
Le string de O2 et array de C ont des propriétés différentes :- une variable string 02 peut être un argument de toute fonction ssi la fonction ne
modifie pas la chaîne passée en argument : ne peut pas être utilisée avec fg()gets(), car l'argument est modifiée par la lecture
--->> String O2 s'utilise comme un vecteur de caractères :
{o2 string ville;char nom[50]; --array Cstrcpy(nom, "Beauport"); --aussi avec strcmp() et strlen()strcpy(ville, nom);. . .}
Page 141
Chaîne O2 et les pointeurs
o2 string r, s, x;...r = "bus_rapide";s = r + r;r += s; -- bus_rapidebus_rapidebus_rapideIF ((s[2:4] == "s_r") && (count(r) == 27) {printf (......)};strcpy(x, r);…
}
Page 142
Effacement complet ou partiel d’une liste/set
Effacement d'une liste :{o2 list(Personne) listePers;listePers[0:15] = list(); -- la liste est mise à nulle.}
Effacement d'un set :{o2 set(Personne) setpers;setpers = set(); --set vide…`}
Page 143
Exécution d’une requête OQL en O2C
O2query( )Fonction pour exécuter les clauses du langage de requête OQL au sein même ducode O2C. Le résultat de la requête peut être un objet ou une valeur sous formed'une variable.
La fonction retourne :0 si tout fonctionne, sinon une valeur != 0 si erreur.{ o2 real limite = 300;o2 real taux ;o2 set(real) s;o2 set(Employe) lesEmployes; -- set non persistantlesEmployes = ABCOptique->employes;o2query ( s,
"select e->salaireFrom e in lesEmployesWhere e->taux < 20.25 " );
display (s); };/* la variable doit être du même type que la réponse de la requête OQL */
A. Gamache BDO-O2SQL ©Page 144
OQL de O2(Langage de requête objet)
Exercices
2012-01-22
André Gamache, professeur associéDépartement d'informatique et de génie logicielFaculté des sciences et de génieUniversité Laval. Québec, Qc, Canada, G1K 7P4Courriel: [email protected]
A. Gamache BDO-O2SQL ©Page 145
O2SQL
• Version O2 de OQL (ODMG) rendue par O2SQL
• O2SQL ne tient pas compte de l’encapsulation en mode query, mais la prend en compte en mode programmation ia O2C.
• Peut interroger les objets et exécuter des méthodes
• Le type du résultat se déduit implicitement de la forme de la requête et n’est pas nécessairement un type déjà présent dans la base : résultat possible : un objet, un ensemble d’objets, liste d’objets structurés, un ensemble de valeurs, ….
A. Gamache BDO-O2SQL ©Page 146
OQL
• Le langage de requête O2SQL utilise des ressources pour interroger les objets de la base:– Objet et valeur nommées– Extension de classe
• Type du résultat nécessaire pour la ré-utilisation avec une variable O2C
• L’interpréteur de O2SQL analyse, optimise et lance l’exécution de la requête
A. Gamache BDO-O2SQL ©Page 147
BD pour interrogation
• Objets nommés:– [Constant] name canada : Pays;– [Constant] name quebec : Ville– [Constant] name montreal : Ville;– [Constant] name champlain : Monument;
• Valeurs nommées : des extensions pour objets– name lesRegions : set(Region);– name lesVilles : list(Ville);
** Constant fixe le nom montreal vomme ville de Montréal et ne peut pas être changé par affectation (partie gauche) subséquente.Ex. montreal = new ville(‘’Québec’’); --(interdit par le constant)
A. Gamache BDO-O2SQL ©Page 148
Requête sur un objet nommé
• Requête élémentaire avec un objet nommé toujours inscrit dans le DD) :
Montreal
1. Type du résultat: objet de classe Ville2. Information recherchée:
Ville : Montréal
Population: 2 000 000
adresseMairie:NoRuecodePostal
cinémas: {nom}
235HochelagaZ3T 4D9{ Lumière, leClap…}
A. Gamache BDO-O2SQL ©Page 149
Projections avec une requête élémentaireutilisant les objets nommés
• montreal->nom ou montreal.nomType du résultat : stringValeur du résultat : Montréal
• montreal.adresse
Type du résultat : tuple(no : integer, rue: string, codePostal : string)Valeur : tuple(no:235, rue: ‘’Hochelaga’’, codePostal: ‘’Z3T 4D9’’)
A. Gamache BDO-O2SQL ©Page 150
Projection avec un attribut de collection
• montreal->cinemas->nom • (requête interdite avec l’attribut multivaleur cinemas)
Nommer le résultat d’une requête:f est un nom de résultat:
define f as req
Où: f est le nom (non persistant) du résultat à la requête req
A. Gamache BDO-O2SQL ©Page 151
Requête avec les collections nommées set et list
• Pour obtenir toute la collection des régions : (avec la valeur nommée de type ensemble:
lesRegions Type du résultat : set(Region)Valeur du résultat : ensemble d’objets de type Region
– La 2è ville :lesVilles[1]
A. Gamache BDO-O2SQL ©Page 152
Filtrage sur les objets : O2SQL
• Sélection de certains objets de la collection avec un filtre formulé avec le O2SQL.
• Structure d’une requête O2SQL :
Select <résultat recherché>From <collections et variables>Where <conditions>
A. Gamache BDO-O2SQL ©Page 153
Recherche avec un attribut d’ensemble
• Le nom des cinémas de Montréal via sa valeur nommée montreal:
Select c->nomFrom c IN montreal->cinemas;
Type du résultat : set(string)
Valeur : { ‘’Lumière’’ , ‘’leClap’’}
Valeur nomméeAttribut type set
A. Gamache BDO-O2SQL ©Page 154
Modèle UML de la base Tourisme
PaysnomP*populationP
VillenomVpopulationVadresseMairie
ADesVilles 1
1..*
PlaceTournomPldescriptionPltarifPladressePl
MuseethemehoraireM
HotelnomHtarifHadresseHetoilesH
logementHlieuxAVisiter 1
1..*1..*1
Class Pays type tuple( nomP : string,populationP : integer,aDesVilles : set(Ville),
public capitale: Ville)methodpublic w_villes(c: Ville):Pays,public r_villes: set(Ville)End;
Class Ville public type tuple (nomV :string,populationV : integer,adresseMairie: string,localiser : Pays,lieuxaVisiter : set(Place),logementH : set (Hotel),End;
Class Hotel type public tuple (public nomH: string,tarifH : real,adresseH : string,etoilesH : integer,ville : Ville)End;
Class PlaceTour type tuple (nomPl : string,descriptionPl : string,tarifPl : real,adressePl : tuple(rue: string, ville:Ville))
End;
Localiser
1
1
Class Musee inherit Place public type tuple (
theme : string,horaireM : string)End;
A. Gamache BDO-O2SQL ©Page 155
Extensions et valeurs nommées de la base Tourisme
Les extensions:
name lesPays : set(Pays)
name lesVilles : set(Villename lesHotels : set(Hotel)name lesPlaces : set(Place)name lesMusees : set(Musee)
A. Gamache BDO-O2SQL ©Page 156
Fouille dans une collection d'objets (extension)
• Afficher le nom de chaque ville du Canada. Ce pays fait l’objet d’un objet nommé:
name leCanada : Pays
Select v->nomVFrom v IN leCanada->adesVilles;
Type du résultat : ensemble de chaînes. set(string)Valeur du résultat : un ensemble de valeurs [ou d’objets]
A. Gamache BDO-O2SQL ©Page 157
Sélection dans un set avec un filtre
Le nom de chaque hôtel de 2 étoiles (**) de la ville de Québec.On a que : name quebec : Ville
Select h->nomHFrom h IN quebec->logementHWhere h->etoilesH = 2 ;
Type de résultat : set (string)
A. Gamache BDO-O2SQL ©Page 158
Jointure avec O2SQL
Afficher le nom des hôtels de 3 étoiles:
L’extension de la classe Ville : lesVilles
Select h->nomHFrom v IN lesVilles, h IN v->logementWhere h->etoilesH = 3;
Utilisation de 2 variables : v pour parcourir chaque objet ville de son extension et une variable h définie en fonction de la valeur courante de v pour parcourir tous les hôtels de la ville courante.
A. Gamache BDO-O2SQL ©Page 159
Jointure avec un filtre d’inclusion
• Affichez les musées de New York*** Classe Musee hérite l’adressePl de la classe PlaceTour
Select mPlFrom m IN lesMuseesWhere m->adressePl.ville->nomV = ‘’New York’’ ;
• Affichez les musées peu importe la villeUn musée est une place à visiter parmi d’autres
Select Distinct m->nomPlFrom v IN lesVilles, m IN v->lieuxaVisiter Where m IN lesMusees;
A. Gamache BDO-O2SQL ©Page 160
Fonction O2query
• Cette fonction a besoin d’un paramètre du type de la réponse de la requête avec de récupérer les valeurs dans le pgm O2C
…o2 set (Personne) m, leTeam;o2 Client x; o2query ( m, "select c from ....); -- m est une variable d’ensemble d’objets. . .
Exemple :{ o2 real limite = 300;o2 real taux ;o2 set(real) s;o2 set(Employe) lesEmployesTemp; -- set non persistantFor (c IN lesCommerces where c->nom = ‘’Natrel’’){lesEmployesTemp = Natrel->employes;o2query ( s, "select e->salaire From e in lesEmployes Where e->taux < 20.25 ");display (nb);... }
Le set lesEmployesTemp n'est pas nommé, donc transitoire (non persistant).
Ensemble de réels
A. Gamache BDO-O2SQL ©Page 161
Fin
• 2001: Le langage OQL malgré ses qualités a été enlevé de la norme ODMG.
• SQL3 sera le langage à privilégier
• Voir les exercices pour plus d’exemples sur les requêtes O2SQL.
Exercices BDOO ©Page 162
Exercices en O2
André Gamache, professeur associéDépartement d'informatique et de génie logicielFaculté des sciences et de génieUniversité Laval. Québec, Qc, Canada, G1K 7P4Courriel: [email protected]
Exercices BDOO ©Page 163
Ex. 1 Base sur les élèves
• Le dossier des élèves d’une école secondaire sont à gérer comme un base OO avec le système O2. Les informations qui définissent un(e) élève sont les suivantes: nom, prénom, date de naissance et sa famille, soit ses frères et ses sœurs inscrits dans cette école. Répondez aux questions ci-dessous. Pour les méthodes demandées, donnez un exemple de leur appel.
– Créer le schéma et la classe Eleve comme seule classe du schéma de la base EleveSec;
– Créer une extension pour rendre persistants les objets de la classe Personne;
Exercices BDOO ©Page 164
Création de méthodes pour accéder aux objets de la base
– Tous les attributs étant privés, définir les méthodes publiques pour lire les attributs: nom, date de naissance et année de la naissance.
– Définir les méthodes pour ajouter une liste d’élèves à sa famille.
– Définir une méthode age pour calculer l’âge d’un élève;– Créer la méthode CalculAge pour calculer l’âge à une année
donnée passée en paramètre.– Définir les méthodes pour ajouter un élève à sa famille.
Exercices BDOO ©Page 165
Définition de la classe Eleve
• Create schema EcoleSec;Import schema O2kit class Date; -- bibliothèque de classes pré définiesClass Eleve private type tuple(
nas : integer,nom : string,prenom string,dateNaiss : Date,famille : set(Eleve))
MethodInit (nas : integer, nom : string, prenom : string),public lireNom : string,public lireDateNaiss : Date,public ajoutFamille (famille : list(Eleve)),public age : integer,public ageAnnee( annee : Date) : integerEnd;
Exercices BDOO ©Page 166
Création de l’extension
• Puisque le schéma comporte une seule classe, il y a normalement au moins 1 extension. Cette dernière est une valeur structurée comme un ensemble d’objets nommées :
• Name lesEleves : set (Eleve);
{LesEleves}Structure d’enssemble
Dictionnaire de données
LesEleves meta description et oid
Exercices BDOO ©Page 167
Définition de la méthode lireNom
• Lire le nom d’un élève identifié par son nas
method C lireNom : string in class Eleve{ o2 Eleve e;For ( e IN lesEleves where e.nas= self->nas) {return e.nom }};
Appel de la méthode:{o2 Eleve p = new Eleve ( 25, null, null,null, set()) ;o2 string nomE;nomE = p->lireNom;};
Exercices BDOO ©Page 168
Fournir la date de naissance d’un élève donné
• Fournir un objet date de naissance d’un élève identifié par son nas :method body lireDateNaiss : Date{o2 Eleve e;For (e IN lesEleves where e.nas = self->nas) {return e.dateNaiss }};
• Appel de la méthode:{o2 Eleve el = new Eleve (55, ‘’Turgeon’’, ‘’Julia’’, nil, set());o2 Date d;d = el->lireDateNaiss;};
Exercices BDOO ©Page 169
Classe pré-défine dans O2Kit: Date
Sachant que la classe Date est définie dans la librairie de schémas O2Kit :• Class Date type tuple(
private day : integer,private month : integer,private year : integer,private long real)
Method public init (day: integer, month: integer, year : integer),
/* (0,0,0) initialisation avec la date du jour */public get_day : integer,public get_year : integer, public get_month : integer,public set_day ( day: integer) : boolean,…End;
Création d’un objet de type Date : o2 Date dn = New Date(3,12,1981);
Exercices BDOO ©Page 170
Date de naissance d’un élève
Sachant que la classe Date importée avec la commande O2 Import fournit les attributs et les méthodes de la classe Date;
method body lireAnneeNaiss : integer{o2 Eleve e;
For ( e IN lesEleves where e.nas= self->nas {return e->get_year}
}; /* get_year est une méthode pré-définie de la classe Date*/
• Appel de la méthode par un objet Eleve:{o2 Eleve el = new Eleve (55);O2 integer y;y = el->lireAnneeNaiss; };
Exercices BDOO ©Page 171
Méthode pour calculer l’âge
Méthode pour calculer l’âge à ce jour d’un élève (self)method body age : integer in class Eleve {o2 Date dateJour;datetJour= new Date (0,0,0); /* date du jour par défaut*/return ((dateJour->get_year) – ((self->dateNaiss) ->get_year));};
• Appel de la méthode:{o2 Date dn = new Date (20,10,1980);o2 Eleve el = new Eleve (35, null, null, dn, set() );O2 integer a;a = el->age; };
Exercices BDOO ©Page 172
Calcul l’âge d’un élève à une année donnée
L’année de référence pour le calcul de l’âge est passée en paramètre.
method body calculAge (annee : integer) : integer in class Eleve{return (annee – (self->get_year))};
• Appel de la méthode:{o2 Eleve el = new Eleve (22, );O2 integer j, annee;annee = 1985;j = el->calculAge(annee);};
Exercices BDOO ©Page 173
Méthode pour ajouter un élève de la famille
Une sœur de l’élève (de nas =1) est inscrite à l’école et doit être ajoutée à la famille de l’élève de nas1 déjà inscrit. Dans l’application O2C, il faut rechercher l’objet de nas = 1:
method body ajoutFamille (membreFam : list(Eleve) in class Eleve{self->famille += membreFam;};
• Appel de la méthode:{o2 Eleve e1 = new Eleve (1, null, null, null, set());o2 list(Eleve) listeE;listeE = list(new Eleve(66,null, null, null, set()));e1->AjoutFamille (listeE);};
Exercices BDOO ©Page 174
Exercice 2
Exercices BDOO ©Page 175
Création du schéma Piece et de ses méthodes
• Dans une société de distribution, on gère deux sortes de pièces: celles achetées directement des usines manufacturières, elles sont dites de base et celles obtenues par assemblage des pièces de base, dites composites
• Exemple : Soit pb1, pb2, pb3 et pb4 des pièces de base acquises de fournisseur. Aussi, soit les pièces composites suivantes :
pc1 : (pb1, pb2) – pièces de base uniques
pc2 : (pb1, pb1, pb3, pb4) -- 2 pièces de base idem
Exercices BDOO ©Page 176
Suite du scénario
• Une base de données Pieces est à créer pour gérer toutes les pièces. Chaque pièce, de base ou composite a un numéro unique. Chaque pièce de base est définie par son prix unitaire, tandis qu’une pièce composite a un coût d’assemblage propre à chaque pièce composite. Une pièce composite peut inclure plusieurs pièces de base de la même sorte, mais aucune pièce composite.
1- Définir les classes est les extensions de cette base Pieces.
2- Ecrire une méthode pour calculer le prix de revient d’une pièce composite quelconque.
Exercices BDOO ©Page 177
Suite de l’énoncé
3- Formulez une méthode pour afficher les numéros des pièces de base utilisées dans la fabrication d’une pièce composite donnée.
À votre disposition: Vous avez plusieurs méthodes de la classe Object et du schéma
O2Kit, ainsi que plusieurs fonctions:– Display méthode pour afficher un objet – Display (attribut) fonction pour afficher une valeur– Count( ) fonction pour compter ou obtenir la taille d’un
ensemble ou d’une liste.– Input (variable) fonction pour lire une valeur
Exercices BDOO ©Page 178
Modèle UML comportant un héritage
Modèle UML de cette base
Piece
noP : integer
nomP : string
PieceComposite
coutAss : real
public prixRevientPC : real
PieceBase
public prix : real
getPrixPB : real
incluesDans 0..*1..*
PieceBC
qte :integer
{c, d}
Exercices BDOO ©Page 179
Schéma et extension de PiecesImplémentation d’une classe-association en O2
Class Piece [private] type tuple(noP : integer, nomP : string);end;
Class PieceBase INHERIT Piece private type tuple (
prix : real,incluesDans : set(tuple (pieceC : PieceComposite, qte: integer ))
method getPrixPB(noP: integer) : realEnd;/* La classe Association est implémentée par un set de tuples. */
Class PieceComposite INHERIT Pieceprivate type tuple ( composants : set(tuple ( pieceB : PieceBase, qte: integer)),coutAss : real)method public prixRevientPC : real,
affiche pieceCompositeEnd;
Exercices BDOO ©Page 180
Les extensions
Comme la spécialisation est {c,d}, la superclasse Piece est abstraite donc pas instantiable. Pour y arriver en O2, il suffit de ne pas créer d’extension. Il a donc une extension que pour chaque sous-classe.
• Name lesPieceBases : set(PieceBase);• Name les PieceComposites : set (PieceComposite);• Aucune extension pour la classe Piece : {c, d}
Dans cet exemple, la recherche de l’objet se fait par l’application, avant l’appel des méthodes :For (p in lesPieceBases Where p->prix > 15.75)
{ appel de méthode}…;}
Exercices BDOO ©Page 181
Méthode getPrixPB
• L’objet est recherché dans l’application, et seul le prix (attribut private) est calculé par la méthode. Dans ce cas-ci , le calcul se réduit à une simple lecture.
method body getPrixPB: real in class PieceBase{return ( self->prix); };
Exercices BDOO ©Page 182
Implémentation de la méthode decalcul du prix de revient d’une pièce composite
Le prix de revient (prixR) = ( qte de pièces de base) * prixPB) + coutAss
La méthode est appelée par un objet de PieceComposite:method body prixRevientPC : real in class PieceComposite{o2 set(tuple(pieceB : PieceBase, qte:integer) ensPB; o2 tuple((pieceB : PieceBase, qte:integer) q;real prixR, prixPC; ensPB = self->composants; --les pièces de base de la PC
For (q in ensPB) prixPC += q.qte * q.pieceB->getPrixPB;return (prixPC + self.coutAss);};
Petite histoire de O2
• Création à l’INRIA (France) : Claude Delobel et François Bancilhon
• Poursuite dans une startup de Versailles (de l’INRIA) (O2 Technologies)
• Commercialisation aux USA à Palo Alto (il y a quelques années)• Rachat par Ardent Software du Texas (groupe très présent dans le
sud-central des USA)• Acquisition par IBM: acquisition de la technologie objet (2002)• Oxymel (France), 2005• Avenir …. ? (1)
(1) Excellent produit mais marketing faible; support et développement fragiles!
Exercices BDOO ©Page 184
FIN