Il programmatore e le sue api

III parte: Si inizia a definire il datamodeldi

In questo articolo mostriamo a grandi linee come sia possibile realizzare un modello di entità partendo da un semplice elenco di "oggetti" e arricchendolo passo dopo passo fino ad arrivare ad un classico diagramma UML in cui siano specificate relazioni di associazione, aggregazione e composizione.

Introduzione

Alla luce di quanto visto nelle puntate precedenti, dovrebbe essere piuttosto chiaro che il processo di sviluppo di un progetto software è una attività complessa (e questo lo si sapeva) che richiede un approccio flessibile, ciclico e pronto in ogni momento a modificare quanto definito nelle fasi precedenti. Questo approccio "flessibile" non deve essere rappresentare la scusa per giustificare un procedimento caotico e anarchico nella realizzazione delle varie componenti del progetto. Il senso di questa filosofia è proprio quanto riportato nella figura numero 1, già presentata nella puntata precedente e che qui per facilitare la lettura riproponiamo.

 

Figura 1 - Il processo di analisi e di definizione del problema è basato su una serie di attività che si rincorrono e che consentono passo dopo passo di arrivare progressivamente a un raffinamento sempre maggiore dei vari manufatti (diagrammi, questionari, documenti vari).

Durante le prime fasi di sviluppo (inteso non come stesura del codice) del progetto, il lavoro deve iterativamente procedere alla definizione del raffinamento dei vari artefatti: questo processo ciclico deve portare in ultima analisi alla realizzazione di un set di classi sufficientemente precise e definite, accompagnato dalla lista delle funzionalità (use case) più dettagliata possibile.
Dopo aver parlato degli approcci metodologici nelle puntate precedenti, è giunto il momento di passare alla parte relativa la definizione dei vari layer architetturali che comporranno il progetto nel suo complesso.
Per ovvi motivi di chiarezza e di semplicità si partirà dallo strato di persistenza, dove i vari oggetti verranno sincronizzati con il sistema di storage.

Object Oriented vs Relazionale

Qualsiasi programmatore che abbia almeno una volta provato a sviluppare una applicazione a oggetti (in un qualsiasi linguaggio di programmazione) che preveda la persistenza di informazioni presso un database relazionale, si sarà reso conto come in realtà questi due modelli, relazionale e OO, non si sposino bene a causa del diverso approccio con il quale i due paradigmi affrontano i rispettivi compiti.
Se infatti nella OOP ci si preoccupa principalmente di poter mappare la realtà che ci circonda cercando di descrivere natura e comportamento degli oggetti (ereditarietà e incapsulamento), capacità di adattamento (vedi polimorfismo) nel modello relazionale tutto è votato alla compattezza dei repository (coerenza e integrità referenziale, non ridondanza) per ottenere come risultato finale un sistema performante.
Un possibile approccio che viene proposto in alcuni manuali di progettazione del software parte dalla definizione del modello delle entità (che poi diveranno classi) e poi con opportuni strumenti o framework di Object Relation Mapping (ORM) permettere alle entità di essere tradotte dal dominio a oggetti a quello relazionale. Per questo motivo la bontà di un ORM (Hibernate, JDO, EJB 3.0, Spring POJOs, etc.) si misura nella sua capacità di effettuare la traduzione nel modo più fedele a quanto definito nel modello OO, ma senza alterare la filosofia di base del modello relazionale.
Questi aspetti, ovvero la definizione del datamodel e la successiva mappatura sul modello relazionale, saranno oggetto delle discussioni di questo e dei prossimi articoli: partendo da quale sia il corretto approccio per definire il datamodel, si procederà nei prossimi articoli ad analizzare pregi e difetti di alcuni dei più importanti e famosi framework di persistenza.
Sulla base di quanto visto nelle puntate precedenti, si ipotizza di aver inziato la fase di analisi (ossia la traduzione formale e schematica di quanto raccolto durante l'intervista iniziale) e di aver raccolto sufficienti informazioni per poter procedere alla definizione delle entità che comporranno il dominio applicativo.

Primo passo: definizione del domain model

Come si è avuto abbondantemente modo di dire nelle puntate precedenti, il software che si deve sviluppare ha come obiettivo quello di fornire all'apicoltore hobbistico, al professionista singolo così come all'azienda apistica, alcuni strumenti per poter svolgere il proprio lavoro di apicoltura, effettuare statistiche sia sulla produzione che sullo stato degli apiari, ottimizzare gli impegni (economici e materiali), controllare lo stato di salute delle varie famiglie di api: il tutto con il fine di massimizzare i guadagni e di salvaguardare la salute delle singole famiglie di api. Importante quest'ultimo aspetto: tutte le operazioni devono sempre avere come obiettivo quello di salvaguardare la salute delle famiglie per non indebolire le colonie e permettere quindi una produzione sempre costante e di qualità dei vari prodotti dell'apiario.
Sulla base delle considerazioni fatte negli articoli precedenti e immaginando di aver raccolto sufficienti informazioni dal cliente su cosa deve esser fatto, l'analista ha immaginato che dovranno essere gestire le seguenti entità:

Apiario

Un apiario è una installazione di una serie di arnie in una determinata zona. Per massimizzare la raccolta di miele e salvaguardare la salute delle famiglie, un apiario deve avere caratteristiche di localizzazione geografica ben precise: massima esposizione a sud (per avere il maggior numero di ore di luce solare), lontananza da fonti inquinanti (fabbriche, strade trafficate, eventuali rifiuti etc.) e deve essere posizionato in una zona calda e poco umida. Per la scelta della posizione, il sistema software non ha nessuna responsabilità se non la memorizzazione del maggior numero di informazioni geografiche, cosa che viene svolta dalla entità Sito.

Figura 2 - Un apiario è un raggruppamento di arnie posizionate in una zona particolarmente adatta alla produzione del miele e al mantenimento in buona salute delle arnie. Nella foto si nota uno sciame naturale che si è momentaneamente posato su un ramo in attesa di trovare una sistemazione definitiva.

 

Apicoltore

È l'attore che svolge la sua attività nell'ambito di una o più organizzazioni o aziende (vedi Azienda). Volendo introdurre un poco di flessibilità alla applicazione e rendere il diagramma più interessate, si farà una ipotesi non necessariamente corrispondente alla realtà: si immagini che un apicoltore possa lavorare come consulente esterno alla azienda (usando un termine più vicino alla tradizione contadina, il modello potrebbe essere quello del bracciante che offriva per ore o giorni la sua forza lavoro al proprietario terriero). In questa situazione non è affatto detto che un singolo apicoltore lavori per una sola azienda ma potrebbe offrire il suo tempo e la sua esperienza a aziende diverse. In particolare si può immaginare che vi siano apicoltori con conoscenze tecniche specifiche, mentre altri potrebbero essere utilizzati come semplici fornitori di braccia e schiene robuste (la raccolta del miele è una operazione molto faticosa e stressante per la spina dorsale dato che un melario carico può pesare 20 kg, mentre una arnia nel periodo di massima produzione può arrivare ai 50-60 kg). Questa assunzione porta due importanti conseguenze: la prima è che la relazione che si instaura fra un apicoltore e l'azienda non è esclusivo per nessuno dei due attori; secondariamente ogni lavoratore può essere utilizzato nell'arco dell'anno con funzioni e ruoli diversi. Si daranno maggiori spiegazioni sulle implicazioni di questa relazione nel paragrafo in cui si presentano le varie relazioni.

Arnia

È una cassetta in legno (per questo viene detta anche semplicemente cassetta), costruita in modo particolare da agevolare la crescita della famiglia, la produzione di miele e le operazioni di controllo e raccolta da parte dell'apicoltore. Di fatto rappresenta la casa dove viene installata una famiglia. Deve essere tenuta sotto controllo per monitorare lo stato di conservazione (ogni tot anni devono essere restaurate e disinfettate).

Azienda

Rappresenta la struttura organizzativa sotto la quale si svolgono tutte le operazioni di produzione del miele e allevamento delle api. Può essere a conduzione familiare, una cooperativa di soci o una SRL. Il nostro scopo non è realizzare un software gestionale, per cui possiamo limitare le informazioni essenziali della azienda.

Intervento

A causa dell'introduzione di un sistema di lavorazione in apiario basato sui ruoli dei singoli apicoltori, ogni operazione svolta dovrà essere schedata, sia per fini statistici, sia per produrre uno storico delle attività svolte. Questa entità di fatto potrebbe essere utile anche per poter disporre di un archivio delle ore lavorative, ad esempio per produrre un canale di comunicazione verso un qualche sistema gestionale.

Famiglia

Ogni arnia contiene una famiglia ossia il gruppo organizzato di api raccolto intorno a una ape regina. È importante tenere sotto controllo l'andamento della singola famiglia per monitorare malattie, anzianità della regina, bontà delle produzioni, e altre informazioni legate alla vita delle famiglie.

SchedaFamiglia (con i sottotipi)

Al fine di verificare la bontà del sistema ORM nella gestione di una gerarchica di oggetti, si sono introdotte le entità SchedaFamiglia, con le sotto entittà SchedaProduzione e SchedaSalute. Per quello che riguarda la logica applicativa, questa organizzazione non è strettamente indispensabile, ma permetterà di effettuare alcune interessanti prove sugli ORM introdotti circa le capacità di mappare le relazioni di generalizzazione-specializzazione.

Sito

Un sito rappresenta un luogo dove viene installato un apiario. Questa entità dovrà contenere tutte le informazioni geografiche relative al luogo di installazione di un apiaro e potrà essere utilizzata come base per l'introduzione di funzionalità di localizzazione geografica oppure di mashup in puro stile web 2.0.

Regina

Dalla regina nascono tutti i membri della colonia e quindi caratterizza in buona parte la forza della famiglia (numero di api), la salute (se è stata selezionata da un ceppo con spiccate caratteristiche di resistenza alle malattie, forte propensione all'igiene della colonia, etc.). È molto importante per l'apicoltore poter tener traccia della provenienza della regina (se è comprata da qualche allevatore o allevata in proprio e allora da quale famiglia proviene) e la sua età. Anche se da un punto di vista pratico la coppia di dati famiglia-regina è la stessa cosa (l'apicoltore infatti in genere valuta la forza della colonia, la sua salute o la propensione alla sciamatura) è importante poter tenere distinte le due entità per semplificare le operazioni di assistenza alla famiglia (p.e. al terzo/quarto anno di vita la regina diminuisce la sua capacità di deporre uova, così come la sua forza "chimica" perde di efficacia, e non è quindi più in grado di coordinare le normali attività della colonia stessa).

Dopo aver elencato tutte le possibili entità che andranno a costituire il dominio applicativo del nostro programma possiamo procedere a darne una prima rappresentazione grafica. Si inizia con un entity diagram UML, ovvero un diagramma dove quelle che poi saranno classi Java, ora sono solamente sinteticamente rappresentate come semplici rettangoli: è rimandata la rappresentazione di tutte quelle informazioni per le quali sono necessarie ulteriori indagini per la loro definizione.

Figura 3 - Per la definizione del domain model il primo passo è quello di procedere alla rappresentazione delle singole entità senza preoccuparsi di specificare relazioni e attribut.

È pratica piuttosto comune, dopo una prima stesura, tornare in modifica, sia aggiungendo che togliendo classi. L'aggiunta prevede l'estrapolazione di informazioni da entità già formate (in questo caso un set di attributi sono isolati e promossi a entità separata), perche‘ si vuole rendere le due entità indipendenti anche se le istanze instaurano legami solo con particolari istanze. Come ben spiegato nel libro di Luca Vetti Tagliati ([LVT], capitolo 7) un componente può essere specializzato in una classe a se‘ stante solo se le varie istanze possono partecipare in relazioni con istanze di aggregati diversi. Si può citare il celebre esempio (come nell'esempio del libro di M. Fowler [UD]) del punto di un piano cartesiano: l'entità punto (classe in OOP) è componente sia di triangoli che di rettangoli, ma l'istanza del punto con coordinate XY può appartenere o a un triangolo o a un quadrato.
L'operazione opposta (aggregazione di entità) capita quando ci si rende conto che due entità (spesso in relazione uno a uno) non necessitano di una gestione isolata e indipendente e di fatto una è un attributo dell'altra.

Secondo passo: prima definizione delle associazioni

Dopo aver definito le entità, si procede disegnando le semplici associazioni che si immagina si possano instaurare fra le entità stesse. In questa fase non è importante capire il tipo di legame, la direzione ne‘ la cardinalità, ma si limita il lavoro nel cercare di comprendere meglio la natura del dominio del problema, al fine di caratterizzare meglio le entità intese singolarmente o come raggruppamento. È anche in questo momento che si possono ulteriormente eseguire operazioni di aggregazione-scomposizione, anche grazie alla definizione dei vari attributi che caratterizzano le singole classi (è plausibile e permesso iniziare a parlare di classi in questa fase).
Sebbene ci sia chi preferisce rimandare a una fase successiva la definizione degli attributi delle classi, può essere utile anticipare tale assegnazione per poter comprendere meglio cosa e come sono strutturate le varie classi. Il diagramma potrebbe a questo punto prendere la forma come quello riportato in figura 4. In questo caso non spiegheremo il significato delle singole relazioni rimandando tale trattazione al caso completo (paragrafo successivo).

Figura 4 - Dopo aver definito le varie entità, si procede alla definizione delle semplici associazioni

Si noti che in questa fase le linee che uniscono le classi sono semplici associazioni che vogliono solamente significare che due entità sono legate fra loro e che quindi interagiscono grazie allo scambio di attributi (sul database questo significherà la creazione di una foreign key). Non ci è dato di sapere se il legame è bidirezionale (scambio simmetrico di attributi nelle due classi che partecipano alla relazione), sulla nature reale della relazione (si tratta di un semplice scambio di puntatori o qualcosa di più?) o sulla direzione della relazione (è la sola classe Arnia a essere informata della relazione con la classe Apiario o è vero anche il viceversa?).

Terzo passo: specializiamo le relazioni in associazione, aggregazione, composizione

Dopo aver a lungo ragionato sulle classi e sulle relazioni che vi intercorrono si può procedere a una migliore precisazione delle singole relazioni. Per poter comprendere il risultato finale (rappresentato in figura 4) vediamo per prima cosa di fare una breve carrellata delle relazioni dandone spiegazione.

Relazione apicoltore-azienda

Come si è avuto modo di esplicare in precedenza, l'azienda è composta da apicoltori, alcuni dei quali possono essere assunti per periodi brevi o addirittura fornire la loro collaborazione solo in occasione di eventi particolari (p.e. durante la smielatura o nello spostamento delle arnie se l'azienda svolge attività di nomadismo). Un apicoltore quindi si aggrega ad una o più aziende in funzione delle reciproche necessità. La gestione deve essere orientata alla massima flessibilità. La cardinalità è 1..* lato Azienda dato che l'apicoltore può lavorare presso una o più aziende, mentre dall'altra parte abbiamo una relazione 0..* perche‘ una azienda potrebbe in teoria non avere alcun apicoltore (ad esempio per vari motivi per un anno potrebbe limitare la propria attività nella vendita di prodotti e non nella produzione diretta).
La direzione è bidirezionale, dato che entrambe le entità hanno bisogno di conoscere i dati dell'altra. In questo caso, per poter dare maggiore rilievo alla entità Azienda si specifica che la relazione è di tipo aggregativo, proprio a sottolineare che l'apicoltore è la parte e l'azienda è il tutto.

Relazione Azienda-Apiario

In questo caso si tratta di una relazione bidirezionale di aggregazione (gli apiari sono gli elementi fondamentali di una azienda) ma non di composizione (anche se si potrebbe pensare il contrario); appare piuttosto evidente che se una azienda cessa la propria attività (o cambia ragione sociale) non è automatica la cancellazione degli apiari (come invece imporrebbe la relazione di composizione), che possono essere ceduti ad altri o anche semplicemente abbandonati a se stessi (evento che ogni apicoltore cerca sempre di evitare per motivi igienici, ideologici, di normativa etc.). La cardinalità è 1-n (piuttosto intuitivo il motivo) e la direzione è bidirezionale (l'azienda deve sapere dove sono gli apiari e un apiario per normativa delle ASL deve essere assegnato a una organizzazione).

Relazione Apicoltore-Apiario

In questo caso particolare, la relazione può instaurarsi se si tiene conto di quanto detto nel paragrafo precedente, ovvero che diversi apicoltori possono eseguire lavori di vario tipo presso uno stesso apiario, in funzione del ruolo che ricoprono (tecnico di medicazione, installatore di apiari, preparazione di nuove famiglie etc.). In questo caso quindi la relazione è caratterizzata da una serie di attributi di associazione. È quindi il caso di una relazione di associazione con classe associativa. È bene tenere a mente che questa associazione ha più che altro scopo didattico, dato che potrebbe capitare piuttosto spesso che non sia del tutto corretta da un punto di vista prettamente teorico. Come ricorda Luca Vetti Tagliati nel suo libro [LVT]

"Nel ricorso alla classe associazione è necessario tenere bene a mente un vincolo implicito, spesso sottovalutato, di una certa importanza: per ogni singola associazione esiste una e una sola istanza della classe associazione"

Cosa che non è detto sia rispettata del tutto in questo caso. Si è voluto comunque introdurre questo legame al fine di poter testare gli ORM a mappare questo caso nel modo più efficiente possibile. Ovviamente la direzione è bidirezionale mentre la cardinalità è n a m.

Relazione Apiario-Sito

Un sito è di fatto un luogo geografico con una serie di attributi che ne caratterizzano la localizzazione nelle tre dimensioni, ma anche le caratteristiche climatologiche come l'esposizione al sole, le temperature medie e umidità (non tanto legate alle condizioni meteorologiche contingenti ma più legate al particolare mircroclima dovuto alle componenti orografiche e idrografiche, come ad esempio il fondo di una valle o la vicinanza a corsi d'acqua). Un sito esiste a prescindere dal fatto che qualcuno decida di installarci delle arnie, per cui le due entità sono semplicemente legate da un legame di associazione monodirezionale (il sito esiste a prescindere e non vorrà mai preoccuparsi delle api che vi svolazzano). La cardinalità è piuttosto ovvia, se si considera che è consuetudine non mettere mai due apiari nello stesso luogo: se ciò dovesse capitare, si possono assimilare allo stesso apiario.

Relazione Apiario-SchedaProduzione

La scheda di produzione serve per raccogliere informazioni circa le singole operazioni di produzione (p.e. le varie smielature stagionali) in modo che si possa tenere traccia per ogni annata del miele prodotto (o cmq di altri prodotti come pappa reale, polline, etc...). La relazione è banalmente n a 1 di tipo bidirezionale dato che entrambe le entità possono o debbono poter accedere all'altra.

Relazione Apiario-Arnia

Un apiario è costituito da arnie. In questo caso la relazione potrebbe essere considerata come un tipico caso di composizione (come nel caso del punto nel piano cartesiano e la sua appartenenza a figure geometriche). Una arnia può essere aggiunta ad un apiario anche in un secondo momento, ma la cancellazione di un apiario non comporta la distruzione dell'arnia (che può essere migrata altrove). Una arnia può inoltre essere spostata in un altro apiario o può essere utilizzata in modo nomade (il nomadismo è una tecnica usata apicoltura per aumentare di molto la produzione del miele e si basa sullo spostamento delle cassette per "inseguire" le fioriture).
Quindi questa è una relazione di aggregazione la cui navigabilità è diretta dall'apiario verso l'arnia: infatti, proprio per la regola dello spostamento da una apiario all'altro, l'arnia non ha molto interesse a sapere dove si trova. La cardinalità è ovviamente 1 a n.

Relazione Arnia-Famiglia

In questo caso il legame è molto stretto, le due entità non possono vivere separatamente (anche se durante la sciamatura le nuove famiglie di api abbandonano le arnie per installarsi altrove, per l'attività apistica non ha senso considerare uno sciame libero). In alcuni casi drammatici l'apicoltore deve eliminare l'arnia e il suo contenuto (la famiglia) a causa di malattie molto gravi che possono estendersi a tutto l'apiario (la peste americana è il caso principale). Quindi è proprio vero che le due entità seguono lo stesso ciclo di vita. Quindi la relazione di composizione è quella corretta. La cardinalità è di 1 a 1 dato che due famiglie (ovvero due nuclei con due regine) non possono convivere.

Figura 5 - Il processo di sciamatura naturale porta alla divisione della famiglia in sotto nuclei più piccoli che poi diventeranno famiglie l'anno successivo. L'apicoltore cerca di prevenire la sciamatura perche‘ porta ad un indebolimento della famiglia con conseguente perdita della produzione annuale. Se questo non è possibile si può cercare di recuperare lo sciame "inscatolandolo" in apposite cassettine porta sciami per il successivo travaso un una nuova e più confortevole arnia.

Relazione Famiglia-Regina

Ogni famiglia ha una sola regina. Durante il periodo delle sciamature le api allevano spontaneamene nuove regine con lo scopo di creare nuovi nuclei di api. Grazie a tecniche piuttosto complesse l'apicoltore controlla questo fenomeno cercando di mediare fra non indebolire troppo le famiglie e creare nuovi nuclei che produrranno miele l'anno successivo.
L'apporto biochimico che la regina porta alla famiglia (feromoni) di fatto controlla e regola il ciclo di vita della famiglie e della produzione. Ad esempio se la regina è vecchia non potrà più regolare in modo efficace i ritmi della colonia: in tale occasione quindi sono le api guardiane (che hanno lo stimolo di aggressività) che uccidono la regina per farne una nuova più forte e giovane. La relazione è quindi monodirezionale dalla famiglia verso la regina, proprio perche‘ la regina non ha nessuna necessità di avere informazioni dalla propria prole.

Figura 6 - La regina passa il suo tempo a deporre uova ed essere nutrita da apposite api demandate a questa operazione (dette ancelle reali). Una regina vecchia o non più forte verrà sostituita dalle api che provvederanno ad allevarne un'altra.

Relazioni Famiglia-Scheda, Scheda-SchedaTrattamenti, Scheda-SchedaSalute

Proprio per tenere traccia dello stato di salute di una colonia, è importante tenere traccia delle varie osservazioni effettuate durante il normale lavoro in apiario. L'apicoltore per semplificare il proprio lavoro vorrà separare le schede relative alle medicazione da quelli che invece sono semplici annotazioni sullo stato di salute e su eventuali malattie sono accadute alla famiglia. Proprio per verificare il comportamento del framework ORM con una gerarchia di classi, queste classi sono legate con una relazione padre (classe Scheda) figli (SchedaTrattamenti e SchedaSalute).

Tutte le relazioni qui descritte possono essere utilizzate con il diagramma UML presentato in precedenza arricchendolo con tutti i dati elencati. Il risultato potrebbe essere (con alcune piccole variazioni frutto di gusto personale) quello riportato in figura 7.

Figura 7 - La versione finale del diagramma delle classi in cui sono state aggiunte le relazioni e le cardinalità.

 

Conclusioni

Come si può notare dalla figura 6 le entità, sono ormai quasi classi a tutti gli effetti, se non per il fatto che mancano ancora attributi e metodi, la cui aggiunta verrà fatta in una successiva fase di lavorazione. Sarà questo l'oggetto della puntata successiva in cui si inizieranno a mostrare le prime prove con i vari motori di persistenza scelti per i diversi test.
Al solito rimando, per chi fosse rimasto affascinato ai temi di apicoltora e produzione del miele, al sito della Mieli d'Italia (vedi [MDI]) e Apicoltura 2000 (vedi [A2])

 

Riferimenti

[FOW] Martin Fowler - Kendall Scott, "UML Distilled", Addison-Wesley Professional

[LVT] Luca Vetti Tagliati, "UML e ingegneria del software", Tecniche Nuove

[LAR] Craig Larman, "UML and Design Patterns", Prentice Hall PTR

[A2] Apicoltura 2000 - portale di apicoltura
http://www.apicoltura2000.it/

[MDI] "Mieli d'Italia: sito della Unione Nazionale Associazioni Apicoltori Italiani"
http://www.mieliditalia.it

Condividi

Pubblicato nel numero
126 febbraio 2008
Giovanni Puliti lavora come consulente nel settore dell’IT da oltre 20 anni. Nel 1996, insieme ad altri collaboratori crea MokaByte, la prima rivista italiana web dedicata a Java. Da allora ha svolto attività di formazione e consulenza su tecnologie JavaEE. Autore di numerosi articoli pubblicate sia su MokaByte.it che su…
Articoli nella stessa serie
Ti potrebbe interessare anche