09. Concetti sui database Object-Oriented

9. Concetti sui database Object-Oriented
Michele Nasti
09. Concetti sui database Object-Oriented
Il primo linguaggio di programmazione object-oriented (O-O) è SIMULA (fine anni ’60). SIMULA
definisce il concetto di classe, che raggruppa la struttura di dati interna di un oggetto in una
dichiarazione di classe e un tipo di dato astratto, che nasconde la struttura interna e specifica tutte
le possibili operazioni esterne, portando al concetto di incapsulamento.
SMALLTALK, sviluppato al Xerox Parc, (anni '70) è uno dei primi linguaggi a incorporare concetti
di message passing ed ereditarietà. SMALLTALK è un linguaggio Object-Oriented puro, a
differenza di linguaggi ibridi come C++, che incorpora concetti O-O nel linguaggio C.
Il linguaggio O-O puro più diffuso al momento è JAVA.
Un oggetto tipicamente ha due componenti: uno stato (o valore) e un comportamento (o
operazioni). Un oggetto è simile ad una variabile, ma con due differenze: può rappresentare una
struttura dati complessa, e può avere una serie di operazioni specifiche, definite dal programmatore.
In un linguaggio di programmazione O-O, gli oggetti esistono solo durante l'esecuzione del
programma (sono detti transienti) . Un database ad oggetti può estendere l'esistenza di un oggetto
memorizzandolo su una memoria secondaria: gli oggetti sono quindi persistenti, esistendo anche
dopo la terminazione del programma che li ha definiti. Gli oggetti persistenti possono essere
condivisi da più programmi.
Un obiettivo dei database O-O è di mantenere una corrispondenza diretta tra gli oggetti del mondo
reale e del database, in modo che gli oggetti non perdano la loro integrità ed identità. A tal fine, essi
forniscono per ciascun oggetto un identificatore univoco di oggetto, detto OID, generato dal
sistema. L'OID può essere visto come equivalente al concetto di chiave primaria nei database
relazionali.
Una caratteristica dei database O-O è che gli oggetti possono essere caratterizzati da una struttura
complessa arbitraria, per contenere tutte le informazioni necessarie. In contrasto, nei database
system tradizionali, l'informazione su un oggetto complesso è spesso frammentata su molte
relazioni o record, portando ad una perdita di corrispondenza tra un oggetto del mondo reale e la sua
rappresentazione nel database.
La struttura interna di un oggetto comprende la specifica di variabili di istanza e di operazioni .
Le variabili di istanza mantengono i valori che definiscono lo stato interno dell'oggetto. Esse sono
simili al concetto di attributo, ma sono incapsulate nell'oggetto e non sono necessariamente visibili
all'esterno. Possono essere di un tipo di dato arbitrario.
Le operazioni specificano le funzioni che possono essere applicate a quell'oggetto. Per incoraggiare
l'incapsulamento, molti sistemi O-O prevedono la definizione delle operazioni applicabili a un
oggetto. In tal caso un'operazione è definita in due parti: la signature (o interfaccia), che specifica il
nome dell'operazione e gli argomenti e il metodo (o corpo), contenente l'implementazione
dell'operazione.
L'incapsulamento consente la modifica della struttura interna di un oggetto e/o
dell'implementazione delle sue operazioni, senza che i programmi che le utilizzano debbano essere
modificati.
Affinché un sistema possa definirsi object- oriented, deve supportare due caratteristiche
fondamentali: Una gerarchia di classi (o ereditarietà) e il polimorfismo degli operatori.
www.ilparticolarenascosto.it
Basi di dati 2 @ Unisa
9.1
9. Concetti sui database Object-Oriented
Michele Nasti
Il concetto di gerarchia di tipo o di classe (o ereditarietà) consente la specifica di nuovi tipi o classi
ereditando la struttura e le operazioni di tipi o classi già definite. In questo modo si facilita lo
sviluppo incrementale dei tipi ed il riuso del codice.
In presenza di polimorfismo degli operatori un nome di operazione può riferire a varie
implementazioni distinte, in base al tipo di oggetti cui è applicato. Esempio: l'operatore “+” è
polimorfo, poiché può essere applicato ad operandi di tipi diversi: se gli operandi sono interi, viene
invocata l'addizione su interi. se gli operandi sono reali, viene invocata l'addizione su reali.
Un problema nei DBMS O-O riguarda la rappresentazione di relazioni tra oggetti. Nei primi DBMS
O-O si riteneva che le relazioni non dovessero essere esplicitamente rappresentate, ma piuttosto
descritte da appropriati metodi che localizzano gli oggetti relati. Questo approccio si è rilevato
sbagliato quando applicato a database complessi con relazioni multiple, poiché non si ha la visibilità
delle relazioni.
Lo standard ODMG 2.0 ha riconosciuto questo problema, ed ora molti modelli di dati O-O
permettono la rappresentazione di relazioni attraverso referenze inverse, cioè memorizzando
nell'oggetto l'OID di oggetti relati.
Costruttori di tipo, struttura ed identificatore di oggetti
Un DBMS O-O fornisce un identificatore univoco a ciascun oggetto memorizzato del database,
l'object identifier: L'OID è immutabile, ed è auspicabile che ciascun OID sia usato una sola volta
(se un oggetto viene rimosso dal DB, il suo OID non deve essere riassegnato).
Alcuni DBMS O-O, utilizzano come OID l'indirizzo in memoria dell'oggetto . Ciò può creare
problemi in caso di riorganizzazione della memoria. Più correttamente, altri sistemi utilizzano un
intero lungo, che, grazie ad una funzione hash, viene mappato sull'indirizzo di memoria
dell'oggetto.
Alcuni modelli O-O richiedono che qualsiasi cosa sia rappresentata come oggetto, sia esso un
valore semplice o un oggetto complesso.
Esempio:
50 → peso in chilogrammi,
50 → età di un uomo
dovrebbero essere il valore di due oggetti diversi.
Per evitare la proliferazione di oggetti, molti OODBMS consentono sia la rappresentazione di
oggetti che di valori.
Lo stato di un oggetto complesso può essere costruito da altri oggetti (o valori) mediante un
costruttore di tipo. Formalmente un oggetto è una tripla (i, c, v), dove:
– i è l'OID,
– c è un costruttore di tipo,
– v è il valore (o stato).
Costruttori di base: atom, set, tuple, list, bag ed array.
Il valore di un oggetto v è interpretato sulla base del valore di c nella tripla (i, c, v):
– se c = atom → v è un valore atomico dal dominio D.;
www.ilparticolarenascosto.it
Basi di dati 2 @ Unisa
9.2
9. Concetti sui database Object-Oriented
Michele Nasti
– Se c = set → v è un insieme di OID {i1, i2, ..., in}.
– Se c = tuple → v è una tupla della forma <a1:i1, a2:i2 ,..., an:in>, dove aj è un nome di
attributo (istanza di variabile) e ij è un OID.
– Se c = list → v è una lista ordinata di OID [i1, i2, ..., in] dello stesso tipo.
– Se c = array → v è un array di OID.
Un bag è identico ad un set, ma non è necessario che tutti gli oggetti siano distinti. Set, list, array e
bag sono detti collection types (o bulk types), per distinguerli dai tipi di base.
Esempio. Un possibile stato di base di dati relazionale dello schema COMPANY.
www.ilparticolarenascosto.it
Basi di dati 2 @ Unisa
9.3
9. Concetti sui database Object-Oriented
Michele Nasti
Una serie di oggetti atomici del database “Company”:
– o1 = (i1, atom, Houston)
– o2 = (i2, atom, Bellaire)
– o3 = (i3, atom, Sugarland)
– o4 = (i4, atom, 5)
– o5 = (i5, atom, Research)
– o6 = (i6, atom, 22-May-78)
Una serie di oggetti complessi del database “Company”:
– o7 = (i7, set, {i1,i2,i3})
– o8 = (i8, tuple, <DNAME: i5, DNUMBER: i4, MGR: i9, LOCATIONS: i7, EMPLOYEES: i10,
PROJECTS:i11>)
– o9 = (i9, tuple, <MANAGER: i12, MGR_STARTDATE: i6>)
– o10 = (i10, set, {i12,i13,i14})
– o11 = (i11, set, {i15,i16,i17})
Un oggetto può essere rappresentato con un grafo, realizzato mediante applicazioni ricorsive dei
costruttori di tipo. Come si costruisce il grafo di un oggetto oi:
1. Si crea un nodo labellato con l'OID ed il costruttore c.
2. Viene creato un nodo per ciascun valore di base del dominio D: Se ha un valore atomico, si
crea un arco orientato dal nodo oi al nodo che rappresenta il valore; se il valore è costruito, si
crea un arco dal nodo oi al nodo che rappresenta il valore costruito.
Rappresentazione dell'oggetto
complesso “Department” (O8
nell‟esempio precedente) per
mezzo di un grafo.
www.ilparticolarenascosto.it
Basi di dati 2 @ Unisa
9.4
9. Concetti sui database Object-Oriented
Michele Nasti
Usando i grafi, è possibile definire oggetti uguali ed identici: due oggetti hanno valori identici se i
grafi sono identici, inclusi gli OID, ad ogni livello. Due oggetti hanno valori uguali se la struttura
del grafo è la stessa, ma ai nodi interni possono corrispondere diversi OID.
Esempio. Consideriamo i seguenti oggetti:
–
o1 = (i1, tuple, <a1:i4, a2:i6>)
–
o2 = (i2, tuple, <a1:i5, a2:i6>)
–
o3 = (i3, tuple, <a1:i4, a2:i6>)
Gli oggetti o1 e o2 sono uguali ma non identici. Gli oggetti o1 e o3 sono identici.
I costruttori di tipo sono utilizzati per definire le strutture dati in uno schema di database O-O. Sono
specificati utilizzando un O-O DDL . Le keyword tuple, set e list definiscono costruttori di tipo. I
tipi di dati standard (boolean, integer, ecc...) definiscono i tipi atomici. Gli attributi che riferiscono
ad altri oggetti sono referenze. Si rappresentano così relazioni tra tipi di oggetti.
Esempio.
← riferimento ad un altro oggetto
Illustrazione 1: La specifica deitipi di
oggetto“Employee”,“Date” e“Department” inO-O
DDL.
Incapsulamento di Operazioni, Metodi e Persistenza
I concetti di information hiding e di incapsulamento possono essere applicati agli oggetti dei
database. La struttura interna dell'oggetto è nascosta, e l'oggetto è accessibile solo attraverso un
certo numero di operazioni predefinite. L‟implementazione di una certa operazione può essere
specificata in un linguaggio di programmazione general-purpose.
www.ilparticolarenascosto.it
Basi di dati 2 @ Unisa
9.5
9. Concetti sui database Object-Oriented
Michele Nasti
Gli utenti esterni dell'oggetto devono solo conoscere l'interfaccia dell'oggetto, che definisce nomi e
argomenti di ciascuna operazione. L'implementazione è nascosta all'utente esterno: essa contiene la
definizione delle strutture interne dell'oggetto e l'implementazione delle operazioni:
– Interfaccia → Signature (o firma)
– implementazione → Metodo .
Un metodo è invocato mediante l'invio all'oggetto di un messaggio di eseguire il corrispondente
metodo. L'esecuzione di un metodo può originare un successivo messaggio a un altro oggetto e così
via. Tipicamente, l'esecuzione di un metodo avviene con la notazione punto:
Esempio: D.no_of_emps determina l'invocazione del metodo no_of_emps sull'oggetto D.
La richiesta di un completo incapsulamento è troppo stringente per applicazioni di database. Un
modo di allentarla è di dividere la struttura di un oggetto in attributi visibili, accessibili in lettura a
operatori esterni o al query language ad alto livello, e attributi nascosti, completamente incapsulati
accessibili solo attraverso operazioni predefinite. Spesso le operazioni di update sono incapsulate,
per definire la semantica delle modifiche sull'oggetto.
Una classe è una definizione di un tipo di oggetto, insieme con le operazioni per quel tipo.
Operazioni tipiche:
– Costruttore di oggetto
– Modificatori di oggetto
– Recupero di informazioni relative all'oggetto
Esempio. La classe Employee:
attributi
operazioni
Non tutti gli oggetti sono permanenti nel database: gli oggetti transienti esistono durante
l'esecuzione del programma e scompaiono con la terminazione del programma. Gli oggetti
persistenti, memorizzati nel database, sopravvivono all‟esecuzione del programma.
Esistono principalmente due meccanismi di persistenza: l'Assegnazione di un nome usato per
ritrovare l'oggetto (naming), oppure rendere l'oggetto raggiungibile da altri oggetti persistenti
(reachability).
Con il meccanismo di naming si intende l'assegnamento di un nome univoco e persistente ad un
oggetto, attraverso cui questo può essere referenziato da altri programmi. Gli oggetti con dei nomi
rappresentano degli entry point attraverso cui si può accedere al db. Non è però possibile assegnare
www.ilparticolarenascosto.it
Basi di dati 2 @ Unisa
9.6
9. Concetti sui database Object-Oriented
Michele Nasti
nomi a tutti gli oggetti del db (che possono essere migliaia): la maggior parte degli oggetti sono resi
persistenti col meccanismo di reachability.
Il meccanismo di reachability funziona rendendo degli oggetti raggiungibili da oggetti persistenti.
Un oggetto B è detto raggiungibile da un oggetto A se una sequenza di referenze nel grafo
dell'oggetto porta da B ad A.
Esempio.
Illustrazione 2: La figura mostra tutti gli oggetti raggiungibili
daO8. Se O8 è persistente, allora lo sono anche tutti gli altri
oggetti presenti nella figura.
Per creare collezioni persistenti usiamo un oggetto di nome N, il cui valore è una lista o un insieme
di oggetti di una classe C. Gli oggetti di C sono resi persistenti aggiungendoli alla lista o insieme, e
rendendoli quindi accessibili da N. Si dice che N definisce una collezione persistente di oggetti di
classe C.
www.ilparticolarenascosto.it
Basi di dati 2 @ Unisa
9.7
9. Concetti sui database Object-Oriented
Michele Nasti
Esempio.
Illustrazione 3: Definizione di una classe
DepartmentSet contenente una collezione di
oggetti Department.
In un modello di DB tipico (ER, modello relazionale, ecc...) si assume che tutti gli oggetti siano
persistenti. Quindi un tipo di entità quale EMPLOYEE, quando è definita, rappresenta la
dichiarazione di tipo per EMPLOYEE e un insieme persistente di tutti gli oggetti EMPLOYEE.
In un approccio O-O, una dichiarazione di classe di EMPLOYEE specifica solo il tipo e le
operazioni per una classe di oggetti. L'utente deve separatamente definire un oggetto persistente di
tipo set (EMPLOYEE) o list (EMPLOYEE), avente come valore una collezione di referenze a tutti
gli oggetti persistenti EMPLOYEE.
Per la stessa classe potrebbero essere definite più collezioni di oggetti persistenti. Assumiamo che
per ogni definizione di classe, il nome della classe riferisca sia alle definizioni di tipo e di
operazione che all'insieme di oggetti persistenti di quella classe.
Gerarchie ed Ereditarietà nei DBMS O-O
Nelle applicazioni di DB esistono numerosi oggetti dello stesso tipo. Ogni DBMS deve offrire la
possibilità di classificare gli oggetti in funzione del loro tipo. Un OODBMS deve inoltre permettere
la definizione di nuovi tipi a partire da altri predefiniti, giungendo ad una gerarchia di tipi.
Un tipo viene definito assegnandogli un nome e definendo un certo numero di attributi e operazioni.
Formato: TYPE_NAME: function, function, ... , function
Esempio. PERSON: Name, Address, Birthdate, Age, SSN
Name, Address, Birthdate e SSN sono implementati come attributi memorizzati. Age è
implementato come metodo per il calcolo dell'età, in base al valore della data di nascita ed alla data
corrente.
Un sottotipo è utile per creare un nuovo tipo simile ma non identico a un tipo predefinito. Un
sottotipo eredita tutte le funzioni del tipo predefinito, che viene detto supertipo.
www.ilparticolarenascosto.it
Basi di dati 2 @ Unisa
9.8
9. Concetti sui database Object-Oriented
Michele Nasti
Esempio. EMPLOYEE : Name, Address, Birthdate, Age, SSN, Salary, Hiredate, Seniority
Possiamo dichiararlo come sottotipo di PERSON: EMPLOYEE subtype-of PERSON: Salary,
Hiredate, Seniority
Esempio. Dato il tipo:
GEOMETRY_OBJECT: Shape, Area, ReferencePoint
Shape è un attributo avente valori in {triangolo, rettangolo, cerchio, ecc ...}.
Area è un metodo per il calcolo dell'area.
Supponiamo di voler definire i sottotipi:
– RECTANGLE subtype-of GEOMETRY_OBJECT: Width, Height
– TRIANGLE subtype-of GEOMETRY_OBJECT: Side1, Side2, Angle
– CIRCLE subtype-of GEOMETRY_OBJECT: Radius
L'operazione Area di GEOMETRY_OBJECT può essere implementata in modo differente per
ciascun sottotipo. L'attributo ReferencePoint può avere un significato differente per ciascun
sottotipo; ad esempio centro per RECTANGLE e CIRCLE, vertice tra due lati per l'oggetto
TRIANGLE, ecc ...
Quando un oggetto viene creato, tipicamente può appartenere ad uno o più dei tipi dichiarati. Ad
esempio:, un oggetto “CIRCLE” è sia di tipo CIRCLE che di tipo GEOMETRY_OBJECT, per
ereditarietà.
Alcuni sistemi O-O prevedono una superclasse di sistema predefinita (detta ROOT o OBJECT), da
cui derivano tutti gli oggetti successivamente definiti. La classificazione procede specializzando
oggetti nelle classi addizionali, creando una gerarchia di classe per il sistema.
Nei DBMS O-O esiste una distinzione tra collezioni persistenti e collezioni transienti: una
collezione persistente contiene oggetti memorizzati permanentemente nel db, e quindi accessibili
da programmi esterni.; una collezione transiente esiste temporaneamente solo durante l'esecuzione
di un programma.
Oggetti Complessi
Uno dei principali motivi che ha portato allo sviluppo di DBMS O-O è la necessità di rappresentare
oggetti complessi. Gli oggetti complessi si dividono in strutturati e non strutturati .
Il supporto di un DBMS ad oggetti complessi non strutturati (detti BLOBs, da Binary Large
Objects) permette di gestire tipi di dati multimediali: immagini bit-map , stringhe di testo lunghe
(documenti) , video , etc. Poiché i dati sono “non strutturati”, il DBMS non ne conosce la struttura,
quindi solo l'applicazione che li utilizza può interpretarne il significato.
Poiché un OODBMS consente agli utenti di creare nuovi tipi , e poiché un tipo include sia la
struttura che le operazioni, possiamo vedere un OODBMS come avente un sistema di tipi
estensibile; è quindi possibile creare librerie di tipi personalizzati.
Negli oggetti complessi strutturati, la struttura è definita dalla ripetuta applicazione dei costruttori di
tipo dell'OODBMS. La struttura dell'oggetto è quindi definita e conosciuta dal DBMS.
www.ilparticolarenascosto.it
Basi di dati 2 @ Unisa
9.9
9. Concetti sui database Object-Oriented
Michele Nasti
Concetti avanzati di Object-Orientation
Il Polimorfismo (o overloading degli operatori) permette che lo stesso nome o simbolo sia legato a
due o più diverse implementazioni dell'operatore, in base al tipo degli operandi. Il compilatore
determina quale operazione applicare in base al tipo degli operandi.
Esempio:
GEOMETRY_OBJECT: Shape, Area, CenterPoint
– RECTANGLE subtype-of GEOMETRY_OBJECT (Shape = „rectangle‟):Width, Height
– TRIANGLE subtype-of GEOMETRY_OBJECT (Shape = „triangle‟): Side1, Side2, Angle
– CIRCLE subtype-of GEOMETRY_OBJECT (Shape = „circle‟): Radius
 La funzione Area persiste per tutti gli oggetti rà una implementazione del metodo diversa per ogni
sottotipo: area è overloaded da diverse implementazioni.
www.ilparticolarenascosto.it
Basi di dati 2 @ Unisa
9.10