Sei sulla pagina 1di 5

UNIVERSIT DEGLI STUDI DI PADOVA

LAUREA IN INFORMATICA




Programmazione ad Oggetti
Relazione di Progetto:
QtDB Strumenti Musicali

Carnovalini Filippo - 1048335




1
1. Implementazione di Contenitore
Per il template di classe Contenitore si scelto di creare un template di lista
doppiamente linkata. Grazie a questa scelta oltre ad essere possibile inserimento ed
eliminazione in qualsiasi punto del contenitore in tempo costante anche possibile
scorrere facilmente (e sempre in tempo costante) il contenuto del contenitore sia in
avanti che allindietro.
Contenitore stato fornito di una classe annidata iteratore, che incapsula un puntatore
a un nodo del contenitore in modo di permettere lo scorrimento ad alto livello senza
dover rendere pubblica laltra classe annidata, nodo.
Si scelto di implementare costruttori di copia e assegnazioni che effettuano copie
profonde, perch operare delle scelte che riducessero lo spreco di memoria sarebbe
stato poco efficace con una lista doppiamente linkata: ogni modifica in un punto
qualsiasi del contenitore avrebbe implicato comunque una copia profonda di tutto il
contenuto. Inoltre, per luso principale di questo contenitore (ovvero questo progetto)
non sono previste copie o assegnazioni di Contenitore.
Nonostante questultima affermazione, Contenitore stato fornito di molti metodi, dei
quali solo alcuni sono stati effettivamente richiamati dallapplicativo creato per questo
progetto. In particolare, si noti che i metodi DeleteAny, DeleteOne, Modify e Move
sfruttano ricerche (in particolare il metodo Search), mentre per le eliminazioni e le
modifiche effettuate dallapplicativo sempre nota la posizione esatta nel contenitore
delloggetto in questione, cosa che renderebbe ridondante luso di questi metodi.
Quanto a Search, esso non utile per le ricerche a livello utente in questa applicazione,
in quanto esso vede solo gli elementi che popolano Contenitore, e opera solo il
confronto di uguaglianza, mentre a livello utente si preferisce fornire una definizione
pi fina di ricerca (che sar approfondita pi avanti). Inoltre popolando il contenitore
con puntatori anzich con oggetti pi descrittivi tale Search diventa ancor meno
interessante. tuttavia comunque utile per definire altri metodi di Contenitore.
Tutti i metodi del templare riportano una breve descrizione a commento nel file
contenitore.h.
2. La gerarchia di classi strumentiMusicali
La gerarchia modella com evidente dal nome le varie categorie di strumenti musicali.
composta da una classe astratta radice, Strumento, che incapsula le caratteristiche
comuni a tutti i tipi di strumento (nome, marca, modello, anno di produzione) e
definisce i metodi che poi saranno usati dalle altre classi figlie. In particolare sono stati
2
forniti dei metodi per ritornare i valori dei vari campi e per confrontarli tra due
strumenti, oltre a un metodo di stampa e un metodo Info che permettono di ottenere
tutti i dati assieme, come offstream nel primo caso e come array di QString nel
secondo. Questo lunico caso in cui si usano elementi di Qt nella gerarchia, per il
semplice motivo che questo metodo stato implementato in un secondo momento per
interfacciare la gerarchia con la GUI, e per comodit si optato per QString piuttosto
che std::string.
Allinterno di strumento.h stato definito anche un tipo enum, nota. Poich si tratta
solo di definire le 12 note musicali si ritenuto sufficiente un tipo enumerazione
piuttosto che una classe completa. Connessi a questo tipo sono state definite le
funzioni castNota, getNota e getTokenNota per permettere le varie conversioni tra int,
string e nota che si fossero rese necessarie.
Le quattro classi derivate di Strumento sono Cordofono, Percussione, Tastiera e Fiato,
che specificano le caratteristiche delle quattro categorie di strumenti. Si noti che non
stata scelta la divisione per sezione dorchestra (ovvero legni, ottoni, archi etc) in
quanto tale divisione specifica il timbro di uno strumento, e non le sue caratteristiche
tecniche, che sono quelle che interessano a questo applicativo.
3. SmartStrumentoPtr
Per allocare allinterno di Contenitore elementi di tutte e quattro le sottoclassi di
Strumento necessario ricorrere al sub-typing, e quindi popolare il contenitore con
puntatori polimorfi a Strumento che possano essere in realt puntatori a oggetti delle
altre classi figlie. Si scelto per di non popolare Contenitore con elementi di tipo
Strumento*, ma di creare un nuovo tipo SmartStrumentoPtr, un puntatore smart che
gestisca la deallocazione degli strumenti allocati nello heap. In particolare, gli oggetti
devono essere deallocati solo se lo SmartStrumentoPtr che viene distrutto quello
contenuto allinterno di Contenitore. Per verificare questo, ogni SmartStrumentoPtr
incapsula due booleani: inserire e inside. I costruttori sono poi progettati in questo
modo: esiste il costruttore di default che pu avere 0, 1 o 2 parametri: se ne ha zero
incapsuler un null pointer, se riceve un Strumento* incapsuler quello con inside=0 e
inserire=0, mentre se riceve anche un valore booleano assegner tale valore a inserire.
Il costruttore di copia poi, se copia uno SmartStrumentoPtr con valore inserire settato
a TRUE imposter il nuovo SmartStrumentoPtr con inside=TRUE. Similmente si
comporta lassegnazione. In questo modo, invocando i metodi di inserimento di
Costruttore aggiungendo tale parametro booleano con valore TRUE il temporaneo che
verr passato al metodo avr inserire=TRUE e di conseguenza lo SmartStrumentoPtr
che verr inserito nel contenitore avr valore inside=TRUE.
3
Di conseguenza, nel distruttore ~SmartStrumentoPtr basta controllare se loggetto che
si va a distruggere ha valore inside=TRUE per decidere se deallocare anche loggetto
puntato.
4. Lapplicativo
Linterfaccia grafica sviluppata con luso delle librerie Qt, e prevede unarea di lavoro
minimale con un area inizialmente vuota dove vengono mostrati i dati contenuti nel
contenitore, affiancata da una bottoniera che permette di effettuare le varie azioni
previste. ogni azione determina la comparsa di una nuova finestra di lavoro fino al
completamento dellazione, per poi tornare alla finestra principale aggiornata.
Si scelto di progettare lapplicazione seguendo il principio del modello concettuale
Model-View-Controller. In particolare vengono istanziati oggetti delle classi Model,
Controller e View, create appositamente a questo scopo.
Model possiede il Contenitore<SmartStrumentoPtr> (chiamato DB) che immagazzina
i dati del database (o meglio laccesso a tali dati, visto che questi sono in effetti allocati
nello heap), fornisce i dati quando vengono richiesti, e inserisce i dati che gli vengono
forniti come da inserire o da aggiornare.
View gestisce tutta linterfaccia grafica. La finestra principale generata direttamente
dalla classe View, mentre le varie altre finestre sono definite dalle classi contenute nella
cartella vista. I vari input dellutente vengono raccolti da questa classe, che poi li invia
a chi deve gestirli.
Controller istanzia Model e View (col nome di modello e vista) oltre alla stessa
QApplication, e funge da ponte tra modello e vista, in particolare per quanto riguarda
la gestione dei vari SIGNAL e SLOT.
5. Ricerca
Per gestire questa particolare funzionalit si deciso di replicare in piccolo il modello
Model-View-Controller per la ricerca, con le classi ControllerRicerca, ViewRicerca e
ModelRicerca. ControllerRicerca comunque una classe di vista, e infatti gestisce anche
la visualizzazione della finestra per linserimento della stringa da ricercare. Inoltre
istanza ViewRicerca e ModelRicerca, oltre a far partire la ricerca stessa. ModelRicerca
contiene un Contenitore<SmartStrumentoPtr> nel quale vengono inseriti gli strumenti
che incontrano i criteri della ricerca, e ViewRicerca mostra tali risultati.
4
Se la ricerca non produce risultato alcuno, viene sollevata uneccezione la quale d poi
luogo a un messaggio derrore (in particolare un QMessageBox::information) e poi crea
una nuova finestra di ricerca. (si suppone infatti che lutente desideri ritentare la sua
ricerca).
La ricerca non cerca elementi esattamente uguali a un elemento fornito dallutente,
perch sarebbe poco pratico operare in tal modo. Invece si richiede linserimento di una
stringa che poi va cercata in un qualunque campo degli strumenti presenti nel
database. Si permette di cercare una stringa che corrisponda parzialmente a una parola
nel database (ad esempio mando corrisponde a mandolino) oppure che debba essere
esattamente uguale (solo mandolino corrisponde a mandolino). In ambo i casi la
ricerca non case sensitive.
Per ottenere questo risultato, si crea per ogni entry del database una stringa che
contiene tutti i dati dello strumento separati da uno spazio, e la si confronta con
unespressione regolare. Nel caso parziale lespressione regolare prevede match con
qualunque stringa che contenga la stringa cercata (chiamata query) preceduta e seguita
da qualsiasi carattere in qualsiasi quantit. nel caso di match totali la stringa query
deve essere preceduta e seguita da uno spazio. (a loro volta seguiti e preceduti da una
quantit qualsiasi di caratteri casuali)
5. Salvataggio e Apertura Files
Il programma permette di memorizzare i dati inseriti nel database e di aprire un file
cos generato per vedere il contenuto di un database salvato. Per ottenere questo scopo
si usa il modulo Xml fornito dalle librerie Qt.
Premendo il relativo pulsante della bottoniera, una prima finestra chiede dove si vuole
salvare il file e che nome assegnargli (o che file aprire nel caso dellapertura). Il file
scelto (tramite doppio click) viene passato al model, che si occupa di generare o leggere
il file xml selezionato.
possibile salvare un database vuoto e poi caricarlo, in tal caso il file .xml conterr
solo lintestazione e il tag generale <strumenti> ma nessun altro tag di popolazione.
Viene fornito assieme al progetto un file .xml di esempio chiamato Popolazione.xml.
5. Specifche di Sistema
Il progetto stato sviluppato su Mac Os X 10.9.4 Mavericks, utilizzando QtCreator
2.4.1 basato su Qt 4.7.4.
5