Blog

Bata Stylosophy Sandali 2016fotoShoes Collezione Primavera Estate SUzLpGjMVq
  • La persistenza nelle applicazioni orientate agli oggetti

    In questo articolo vedremo in cosa consiste la gestione dei dati con la persistenza e nel contesto delle applicazioni orientate agli oggetti, in relazione con SQL, Java JDBC e le soluzioni ORM come Hibernate.

    Ormai praticamente tutte le applicazioni software di una certa importanza utilizzano un database, poiché uno dei pilastri programmi consiste nella memorizzazione e nella gestione di dati (come prodotti, clienti, ordini, fatture, etc …).
    Con l’esplosione di internet, l’utilizzo dei database è notevolmente aumentato, anche se gli utenti finali non ne sono consapevoli. La memorizzazione degli articoli di questo blog, ad esempio, utilizza una database che l’applicazione interroga continuamente.

    La possibilità di far sopravvivere i dati all’applicazione che li ha creati viene definita persistenzaGuess Acqusita Sandali Prezzi Online I DonneCompara E Outlet trdshQ. Il salvataggio di file su un hard disk o in un database sono esempi di persistenza. La persistenza è un concetto fondamentale nello sviluppo di applicazioni software. Se un sistema informativo non avesse la possibilità di conservare i dati quando una volta spento, sarebbe di scarsa utilità pratica.
    Quando si parla di persistenza nei linguaggi orientati agli oggetti (come Java), di solito ci si riferisce alla memorizzazione dei dati in un database relazionale, utilizzando SQL. I database relazionali forniscono un approccio molto flessibile e robusto per la gestione dei dati.

     

    I database relazionali si basano sul linguaggio SQL. Le applicazioni object-oriented per la gestione dei dati relazionali devono usare il linguaggio SQL, ad esempio mediante interfacce JDBC (vedi un articolo su Java e JDBC). Se un’istruzione SQL (ad esempio una SELECT) viene incorporata nel codice Java, si utilizza l’API JDBC per legare gli argomenti per preparare i parametri della query, eseguire la query, scorrere la tabella dei risultati della query, recuperare i valori dall’insieme dei risultati, etc … Si tratta di un’operazione di accesso ai dati di basso livello; gli sviluppatori di applicazioni non vogliono perdere tempo ad occuparsi dell’accesso dati di basso livello, ma concentrarsi a scrivere codice che salva e recupera gli oggetti (le istanze delle classi) dal database.

    Questo non vuol dire che i database relazionali non sono la scelta corretta per la persistenza di oggetti in applicazioni Object Oriented (OO), ma piuttosto che i due paradigmi (la modellazione degli oggetti nella programmazione orientata agli oggetti e la modellazione dei dati nei database relazionali) non corrispondono del tutto.

     

    In un’applicazione orientata agli oggetti, la persistenza consente ad un oggetto di sopravvivere al processo che lo ha creato. Lo stato dell’oggetto può essere memorizzato sul disco, ed è possibile ricreare un oggetto con lo stesso stato.
    Questo non vale per singoli oggetti, ma per intere reti di oggetti interconnessi che possono essere resi persistenti e poi ricreate in un altro momento. I moderni database relazionali forniscono una rappresentazione strutturata dei dati da rendere persistenti, consentendone la gestione CRUD (Create Read Update Delete), l’ordinamento, la ricerca e l’aggregazione dei dati. I RDBMS (Relation Data Base Management Systems) gestiscono la concorrenza dei dati, consentono la condivisione dei dati tra più utenti e applicazioni, garantiscono l’integrità dei dati attraverso regole implementate con dei vincoli, forniscono sicurezza a livello dei dati, etc …

    La rappresentazione tabellare strutturata dei dati del modello relazionale è però diversa dalla rappresentazione delle entità di business dell’applicazione orientata agli oggetti.  Se il database di un sito e-commerce ha le tabelle PRODOTTO, CATEGORIA e VENDITE, ad esempio, l’applicazione Java definisce le classi Prodotto, Categoria e Vendite, ma piuttosto che gestire le righe e le colonne di un resultset SQL, la logica di business dell’applicazione userà le istanze del modello di dominio come una rete di oggetti interconnessi. Ogni istanza di un prodotto avrà un riferimento a un elemento categoria, ed ogni istanza della classe Vendita avrà un riferimento a un’istanza di un prodotto. La logica di business non viene eseguita nel database (con delle stored procedure ad esempio), ma viene implementato nel codice orientato agli oggetti (ad esempio Java) dell’applicazione. Questo permette alla logica di business di fare uso di sofisticati concetti OO, come l’ereditarietà e il polimorfismo. Allo stesso modo, il risultato di una proiezione di dati da di una tabella SQL o di una JOIN è sempre un dato in forma tabellare, che è molto diverso dal grafo di oggetti interconnessi usato della business logic dell’applicazione. Questo disallineamento tra i due sistemi di rappresentazione dei modelli di dati viene definito paradigm mismatch.

     

    Il paradigm mismath (o mancata corrispondenza del paradigma) tra modellazione ad oggetti e relazionale si articola su diversi livelli. Cominciamo da quello più semplice e vediamo subito la mancata corrispondenza. Continuando con l’esempio dell’applicazione e-commerce, supponiamo di avere una classe User che rappresenta l’utente del sistema, e un’altra che rappresenta le informazioni sui dettagli di fatturazione dell’utente BillingDetails. Un utente può avere molti BillingDetails e la relazione può essere navigata in entrambe le direzioni.
    Le classi che rappresentano queste entità sono molto semplici: la seguente per l’utente

    public class User {
      private String username;
      private String name;
      private String address;
      private Set billingDetails;
      // metodi accessori getter/setter, metodi business, etc.
      ...
    }

    e la seguente per i dettagli di fatturazione:

    public class BillingDetails {
      private String accountNumber;
      private String accountName;
      private String accountType;
      private User user;
      // metodi accessori getter/setter, metodi business, etc.
      ...
    }
    Vendita Giommi Online Sandalo Tacco Confort Saldo A In Con 29€ qpMVSzGU

    Una possibile modellazione SQL per questo per la tabella USERS è la seguente:

    create table USERS (
      USERNAME varchar(50) not null primary key,
      NAME varchar(100) not null,
      ADDRESS varchar(100)
    )

    e quella per la tabella BILLING_DETAILS:

    create table BILLING_DETAILS (
      ACCOUNT_NUMBER varchar(15) not null primary key,
      ACCOUNT_NAME varchar(100) not null,
      ACCOUNT_TYPE varchar(2) not null,
      USERNAME varchar(50) foreign key references user
    )

    La relazione tra le due entità è rappresentata con la chiave esterna USERNAME in BILLING_DETAILS.

    Vendita Giommi Online Sandalo Tacco Confort Saldo A In Con 29€ qpMVSzGU

    Ora, vediamo cosa succede se si considera qualcosa di un po’ più realistico.
    La mancata corrispondenza del paradigma sarà più evidente quando aggiungiamo più entità e relazioni all’applicazione.
    In questo esempio un indirizzo dell’utente è stato pensato come una variabile String. Ma se avessimo bisogno di memorizzare via, città, stato, paese e CAP separatamente? Ovviamente potremmo aggiungere queste proprietà direttamente alla classe, ma poiché è molto probabile che altre classi useranno le informazioni di tipo indirizzo, ha più senso per creare una classe Address. Aggiorniamo quindi il modello delle classi.

     

    Si deve aggiungere una tabella degli indirizzi? Non necessariamente. Le informazioni sull’indirizzo si possono anche mantenere nelle singole colonne della tabella USERS (così non serve la join se si desidera recuperare l’utente e l’indirizzo in una singola query). Oppure si può creare un datatype SQL definito dall’utente per rappresentare un indirizzo e di utilizzare una singola colonna del nuovo tipo nella tabella USERS, invece di usare diverse colonne.
    In sostanza, possiamo scegliere di aggiungere più colonne o una singola colonna (di un nuovo tipo di dati SQL). Questo è chiaramente un problema di granularità.

     

    Aggiungere un nuovo datatype al database per memorizzare gli indirizzi delle istanze Java in una singola colonna può sembrare un buon approccio, ma la gestione dei tipi di dati definiti dall’utente (UDT, user-defined datatypes) può generare diversi problemi. Ad esempio ciascun DBMS implementa la propria gestione dei tipi di dati definiti dall’utente, con conseguente perdita di portabilità tra i diversi DMBS. La mancanza di uno standard per una funzionalità così importante è la conseguenza della guerra tra produttori di database che nasce dalla metà degli anni ’90 e gli sviluppatori sono ormai rassegnati a questo stato di cose. L’utilizzo di UDT non è quindi di solito la soluzione prescelta e normalmente si preferisce aggiungere le colonne con i tipi standard SQL alla tabella USERS.

    create table USERS (
      USERNAME varchar(50) not null primary key,
      NAME varchar(100) not null,
      ADDRESS varchar(100),
      ADDRESS_STREET varchar(50),
      ADDRESS_CITY varchar(50),
      ADDRESS_STATE varchar(30),
      ADDRESS_ZIPCODE varchar(5),
      ADDRESS_COUNTRY varchar(30)
    )

    I livelli di granularità delle classi del modello del dominio dell’applicazione vanno da quello grossolano (la classe User), a quello medio (la classe Address) a quello fine (la singola proprietà della classe Address). Lato SQL ci sono solo due livelli di granularità: a livello di tabella e a livello di singola colonna.

     

    Se l’applicazione e-commerce su cui stiamo lavorando richiede pagamenti con carta di credito, account paypal e bonifico bancario, il modo migliore per gestire questo requisito nel modello è utilizzare l’ereditarietà, rendendo astratta la classe BillingDetails e creando le sottoclassi CreditCard, Paypal e BankAccount. Ciascuna di queste sottoclassi definisce proprietà e metodi diversi.

    Pietrasanta Calzoleria Zoccoli Sandali La Rapida HomeFacebook E tsQCxrBohd

    Anche se SQL supporta le supertable e le subtable, l’ereditarietà applicata alle classi è un’ereditarietà di tipo e una tabella non è un tipo. I DBMS non supportano l’ereditarietà di tipo o di tabella, e in ogni caso non usano una sintassi standard. In più può emergere anche il problema del polimorfismo. La classe User ha un’associazione polimorfica con la superclasse BillingDetails: a runtime un oggetto User può usare un’istanza di ciascuna delle sottoclassi di BillingDetails, quindi occorre avere delle query polimorfiche che restituiscano le istanze delle sottosclassi di BillingDetails. I DBMS non hanno un modo diretto/standard per rappresentare un’associazione polimorfica. Un constraint di tipo foreign key può puntare ad una tabella, non a più tabelle.

     

    Java definisce due tipi di identità: uno legato all’identità degli oggetti (verifica mediante un controllo del tipo a == b) e uno legato all’equivalenza dei valori delle istanze (verifica mediante un controllo del tipo equals()). Entrambi sono diversi dall’identità di una riga in un database, rappresentata dalla chiave primaria, con conseguente disallineamento tra modello a oggetti e modello del database.

    Un altro problema legato all’identità del modello su database riguarda la scelta della chiave primaria USERNAME della tabella USERS, che rende problematico modificare lo username (occorrerebbe modificare la colonna USERNAME della tabella USERS e la chiave esterna USERNAME della tabella BILLING_DETAILS). Per risolvere questo problema è possibile usare una chiave surrogata, cioè una colonna chiave primaria che non ha significato per l’utente (ad esempio, un campo autoincrementante).

    Vendita Giommi Online Sandalo Tacco Confort Saldo A In Con 29€ qpMVSzGU
    create table USERS (
      USER_ID bigint not null primary key,
      USERNAME varchar(15) not null unique,
      NAME varchar(50) not null,
      ...
    )
    create table BILLING_DETAILS (
      BILLING_DETAILS_ID bigint not null primary key,
      ACCOUNT_NUMBER VARCHAR(10) not null unique,
      ACCOUNT_NAME VARCHAR(50) not null,
      ACCOUNT_TYPE VARCHAR(2) not null,
      USER_ID bigint foreign key references USER
    )

     

    La natura delle associazioni (rappresentate dalle relazioni tra le entità) è diversa tra il modello ad oggetti ed io modello relazionale. I linguaggi OO rappresentano le associazioni con riferimenti agli oggetti (puntatori) e sono direzionali. Se un’associazione tra due oggetti deve essere navigabile in entrambe le direzioni deve essere definita due volte, cioè in ciascuna classe.

    public class User {
      private Set billingDetails;
      ...
    }
    public class BillingDetails {
      private User user;
      ...
    }
    

    Le associazioni di tipo chiave esterna dei database relazionali non sono direzionali, nel senso che la navigazione non ha senso, poiché mediante le JOIN si creano rappresentazioni di dati arbitrarie da tabelle associate tra loro.

    Un altro disallineamento tra i due modelli riguarda la molteplicità di un’associazione. Non è possibile determinare la molteplicità di un’associazione unidirezionale guardando come sono fatte le classi Java. Le associazioni tra oggetti possono essere many-to-many, mentre le associazioni tra tabelle invece sono one-to-many o one-to-one.    

    Quando in un linguaggio OO come Java occorre accedere ai dati, per esempio le informazioni di pagamento dell’utente, lo si fa utilizzando la normale navigazione della rete dell’oggetto, chiamando un metodo del tipo

    user.getBillingDetails().getAccountNumber()West Leather Sandal Nicetime Wedge Nine XkiuPOZ

    navigando quindi da un oggetto ad un altro, seguendo i puntatori tra le istanze degli oggetti. L’associazione ha una direzione (dall’oggetto User all’oggetto BillingDetails), se il riferimento all’oggetto viene specificato solo da un lato, come nell’esempio in figura l’oggetto User ha un riferimento agli oggetti di tipo BillingDetails.

     

    Dall’oggetto User è quindi possibile recuperare gli oggetti BillingDetails associati, ma non è possibile il contrario (a meno di inserire un riferimento all’oggetto User su BillingDetails). Per quanto riguarda la relazione sul database, la presenza di un constraint di tipo chiave esterna tra le due entità consente la navigazione in ambo le direzioni con la JOIN.

    Per recuperare gli stessi dati dal database occorre una join del tipo:

    SELECT *
      FROM users u LEFT OUTER JOIN billing_details bd ON bd.user_id = u.user_id
     WHERE u.user_id = 1067;

    In questa join occorre sapere a quale parte della rete di oggetti devi accedere prima di cominciare la navigazione dell’oggetto.

    Vendita Giommi Online Sandalo Tacco Confort Saldo A In Con 29€ qpMVSzGU

    Un altro disallineamento tra i due paradigmi è dovuto al numero di accessi al database. Ogni soluzione di persistenza degli oggetti fornisce una modalità per accedere ai dati degli oggetti associati quando si accede all’oggetto per la prima volta. Tradotto nel contesto dei database relazionali equivarrebbe all’esecuzione di una SELECT per ciascun nodo della rete, mentre per migliorare l’efficienza del recupero dei dati da un database occorre minimizzare il numero di richieste al database stesso.

     

    Tutte queste differenze tra i due paradigmi rendono più complicata la modellazione degli stessi dati nelle due modalità (ad oggetti e relazionale) e costringono gli sviluppatori di applicazioni OO a gestire caso per caso ciascuno di quesi disallineamenti.

    In un articolo successivo vedremo come le soluzioni di tipo Object Relational Mapping (ORM) come Hibernate risolvono questi problemi e riducono il gap tra il paradigma relazionale e quello ad oggetti.

     

    Giulio Cantali – IT Consultant

    Creatore di Database Master, il primo percorso per diventare esperti di database

Lascia un commento

Di Passaggi Dei Come Sandali Pulire Cuoio13 XkiPZuO

Se vuoi condividere la tua opinione, lascia un commento

Puoi usare questi tag e attributi: HTML:

<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code class="" title="" data-url=""> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong> <pre class="" title="" data-url=""> <span class="" title="" data-url=""> 

R8514 Melluso Zeppa Ebay Sportivo Sandali Primaveraestate Nero Donna qpzVMUS

Vendita Giommi Online Sandalo Tacco Confort Saldo A In Con 29€ qpMVSzGU