• Non ci sono risultati.

Librerie e framework

5.2 Progetto di sistema

5.2.2 Librerie e framework

Durante la scomposizione in sottosistemi bisogna infine considerare la di-sponibilit`a di librerie e di framework . Precisiamo che qui usiamo il termine “libreria” in un significato diverso da quello comune: di solito si intende con questo termine un componente fisico, cio`e un file contenente dei moduli collegabili (p.es, i file .a e .so sui sistemi Unix, .lib e .dll sui sistemi Windows), o analoghi moduli precompilati per linguaggi interpretati (come i

client 1 client 2 server client 1 client 2 server backend comp 1 comp 2 repository pipeline

client−server a 1 livello repository

client−server a 2 livell1 (two−tier)

stadio 1 stadio 2 stadio 3

Figura 5.11: Architetture standard.

file .jar in ambiente Java). Qui invece parliamo di librerie e framework dal punto di vista logico, ricordando che tutti e due i tipi di componenti vengono realizzati e distribuiti come librerie fisiche.

Una libreria logica `e una raccolta di componenti che offrono servizˆı ad un livello di astrazione piuttosto basso. Un framework contiene invece dei componenti ad alto livello di astrazione che offrono uno schema di soluzione preconfezionato per un determinato tipo di problema. Le librerie, quindi, si usano “dal basso verso l’alto”, assemblando componenti semplici e predefiniti per ottenere strutture complesse specializzate, mentre i framework si usano “dall’alto verso il basso”, riempiendo delle strutture complesse predefinite (delle “intelaiature”) con dei componenti semplici specializzati.

Le librerie e i framework sono componenti pronti all’uso (o, come si dice, off the shelf ), generalmente forniti da produttori esterni e non modificabili. Nella maggior parte dei casi l’uso di tali componenti `e molto vantaggioso sia dal punto di vista del processo di sviluppo che della qualit`a, e in particolare dell’affidabilit`a, del prodotto finale. Ovviamente una scelta accurata fra i componenti disponibili ha un’importanza cruciale per il successo del progetto, e questa scelta dipende sia da fattori tecnici, come le funzioni e prestazioni dei componenti, sia da fattori economici ed organizzativi, come le licenze d’uso

5.2. PROGETTO DI SISTEMA 159 «subsystem» InterfBiblio Presentazione Amministrazione «subsystem» Amministrazione Registri «subsystem» RegistroBibliotecari «subsystem» Catalogo RegistroUtenti «subsystem» RegistroPrestiti «subsystem» «subsystem» Persistenza «subsystem» MySQL Persistenza Database IGestUtenti IGestLibri IGestPrestiti

IRegPrest ICatal IRegUtenti

IRegBibl

IPersist

IMySQL

Figura 5.12: Scomposizione per strati e partizioni

e l’assistenza tecnica. Se fra i componenti pre-esistenti non se ne trovano di adatti allo scopo, naturalmente resta la possibilit`a di svilupparli ex novo.

Infine, conviene ricordare che una libreria o un framework possono essi stessi essere sviluppati e venduti come prodotto finale.

Librerie

Una libreria pu`o essere una raccolta di sottoprogrammi globali (cio`e non ap-partenenti a classi) o di classi (Fig. 5.14). In tutti e due i casi l’insieme delle operazioni disponibili viene chiamato interfaccia di programmazione o API (Application Programming Interface). Nel primo caso, la libreria si pu`o rappresentare in UML come una classe, un componente o un package con lo stereotipo ≪utility≫. Nel progetto architetturale non `e necessario mostrare la struttura interna della libreria, e di solito non serve nemmeno elencare le operazioni dell’interfaccia di programmazione. Nemmeno nel

pro-RegistroBibliotecari RegistroPrestiti Catalogo RegistroUtenti Amministrazione

Presentazione

Persistenza

Database

Figura 5.13: Scomposizione per strati e partizioni

getto in dettaglio `e necessario, generalmente, mostrare queste informazioni, anche se in certi casi pu`o essere utile esplicitare quali parti dell’interfaccia di programmazione vengono usate, e con quali classi della libreria si interagisce.

Connection Result Query Database «library» double ceil(double x) double abs(double x) ... double floor(double x) «utility» mathlib

Figura 5.14: Due tipi di librerie.

Framework

Come abbiamo detto, un framework offre uno schema di soluzione preconfe-zionato per un determinato tipo di problema, e viene usato in un’applicazione particolare specializzandone alcune caratteristiche. Questa specializzazione

5.2. PROGETTO DI SISTEMA 161 avviene generalmente per mezzo del polimorfismo: il framework offre al pro-gettista delle classi e delle interfacce il cui comportamento viene specializ-zato derivando altre classi in cui si possono ridefinire i metodi delle classi e interfacce originarie, ed aggiungere ulteriori funzioni.

Un esempio (evidentemente semplificato) di framework viene mostrato in Fig. 5.15. Un’interfaccia grafica `e formata da elementi (Widget) che possono essere composti o semplici. Gli elementi composti sono, per esempio, finestre, pannelli e men´u, e tutti hanno l’operazione add(), ereditata da Compound, che permette di aggiungere un widget all’elemento composto. Gli elementi semplici sono, per esempio, bottoni e campi per l’inserimento di testi, ed hanno varie operazioni specifiche di ciascuna classe. In particolare, la classe Button`e astratta, avendo nella propria interfaccia l’operazione astratta ac-tion() che rappresenta, una volta implementata, l’azione da eseguire quando un particolare bottone viene “cliccato”.

Widget Simple Compound Window TextField Button Panel Menu add(Widget*) setTitle(string) string getText() action()

. . .

. . .

Figura 5.15: Un semplice framework.

Supponiamo di voler realizzare un’interfaccia in cui una finestra contie-ne un bottocontie-ne e un campo testo, dove il bottocontie-ne serve a scrivere sull’uscita standard il contenuto del campo testo preventivamente riempito dall’utente. Tutti i meccanismi a basso livello per la gestione del mouse, della tastiera, della visualizzaizone grafica sono forniti dal framework, oltre alla struttura logica ed ai meccanismi di interazione fra i vari elementi. Il programmato-re deve soltanto scriveprogrammato-re una classe (p.es., MyButton) derivata da Button che implementi l’operazione action() nel modo desiderato, quindi scrivere il programma principale dell’operazione, in cui si istanzia una finestra e vi si

aggiungono un’istanza di TextField e una di MyButton. La Fig. 5.16 mostra la struttura risultante. Widget Simple Compound Window TextField Button Panel Menu MyButton add(Widget*) setTitle(string) string getText() action() { tf_ = tf; } MyButton(TextField* tf) { cout << tf_−>getText(); } action() {

Window* w = new Window; main()

TextField* t = new TextField; MyButton* b = new MyButton(t);

w−>add(t); w−>setTitle("Main Window"); w−>add(b); } . . . . . . TextField* tf_ MyButton(TextField* tf) action() FRAMEWORK APPLICAZIONE

Figura 5.16: Uso di un framework in un’applicazione.

Un framework pu`o essere rappresentato in UML come un componente o un package. Nemmeno per i framework, come gi`a visto per le librerie, `e generalmente richiesta una rappresentazione della struttura interna.