• Non ci sono risultati.

La fase di progetto produce alcuni documenti che descrivono l’architettu-ra del sistema. Tali documenti sono scritti in parte in linguaggio natul’architettu-rale (possibilmente secondo qualche standard di documentazione che stabilisca la struttura dei documenti) e in parte mediante notazioni di progetto testuali e grafiche. Le notazioni testuali descrivono ciascun modulo usando un lin-guaggio simile ai linguaggi di programmazione, arricchito da costrutti che specificano le relazioni fra i moduli e descrivono precisamente le interfacce, e spesso privo di “istruzioni eseguibili”. Le notazioni grafiche rappresentano in forma di diagrammi i grafi3 definiti dalle relazioni. I metodi di progetto pi´u usati nella pratica sono basati su linguaggi grafici integrati da linguaggi testuali.

4.3.1 Unified Modeling Language

Il linguaggio UML, gi`a visto nel capitolo relativo ai linguaggi di specifica orientati agli oggetti, `e anche un linguaggio di progetto. Nella descrizione di un’architettura si possono usare gli stessi concetti (e le relative notazioni) usate in fase di specifica dei requisiti, ma con un pi´u fine livello di dettaglio: per esempio, in fase di progetto si devono specificare precisamente il numero e i tipi degli argomenti di operazioni di cui, in fase di specifica, si era dato solo il nome. Inoltre l’UML fornisce delle notazioni adatte a esprimere dei concetti propri della descrizione architetturale, come la struttura fisica dello hardware e del software. Vedremo nel seguito alcuni esempi di applicazione dell’UML.

4.3.2 CORBA Interface Description Language

Come esempio di notazione testuale di progetto (anche se di espressivit`a alquanto ristretta), consideriamo (oltre a quella mostrata nel libro di testo),

3

Ricordiamo che un grafo `e un concetto matematico, mentre un grafico `e un oggetto fisico (che pu`o anche rappresentare un grafo).

4.3. LINGUAGGI DI PROGETTO 143

il linguaggio CORBA IDL4, orientato alla descrizione di sistemi CORBA (Common Object Request Broker Architecture). L’architettura CORBA si basa su un modello computazionale orientato agli oggetti, un’infrastruttura software di comunicazione, e un insieme di librerie di componenti software, e serve a sviluppare applicazioni distribuite.

Nel modello CORBA i componenti fondamentali di un’applicazione sono oggetti che comunicano in modo indipendente sia dalla posizione fisica che dall’implementazione delle rispettive controparti. Un oggetto pu`o richiedere servizi ad un altro oggetto “ignorando” su quale calcolatore si trova, attra-verso quale protocollo avviene la comunicazione, in che modo e con quale linguaggio `e stato implementato. In questo modo il funzionamento di un sistema distribuito `e interamente svincolato dall’implementazione dei singoli oggetti.

Chi progetta un oggetto CORBA ne specifica l’interfaccia usando il lin-guaggio IDL, e lo implementa nel linlin-guaggio di programmazione prescelto, con l’aiuto di un compilatore IDL che traduce la specifica IDL nel linguaggio di programmazione (per esempio, Ada o C++). Il compilatore IDL produce anche del codice che serve a collegare l’applicazione al supporto run-time che provvede alla comunicazione fra oggetti.

Chi progetta un cliente di un oggetto CORBA si serve del compilatore IDL per tradurre la specifica IDL di tale oggetto nel linguaggio di programmazione in cui viene implementato il cliente. Anche in questo caso il compilatore IDL produce del codice ausiliario per integrare l’applicazione (la parte cliente) col sistema di comunicazione.

L’IDL `e un linguaggio orientato agli oggetti puramente dichiarativo, es-sendo privo di istruzioni procedurali, come assegnamenti, cicli e simili. Ha un controllo statico dei tipi, anche se permette di dichiarare parametri e ri-sultati il cui tipo non `e noto a tempo di compilazione, ed offre un insieme di tipi base analoghi a quelli dei linguaggi di programmazione, dai quali si possono costruire tipi derivati, come le strutture (nel senso del C++, chiama-te record in altri linguaggi), gli array a dimensione fissa e le sequenze (array a dimensione variabile). La definizione di un’interfaccia `e analoga (anche sintatticamente) alla definizione di una classe in C++, con alcune differenze fra cui le pi´u importanti sono queste:

• tutti membri sono pubblici;

4

Oltre al CORBA IDL, che d’ora in poi chiameremo semplicemente IDL, esistono altri linguaggi chiamati IDL.

• si possono dichiarare solo membri funzione;

• non si possono definire le implementazioni dei membri funzione; • non si possono definire interfacce all’interno di interfacce.

A proposito dell’impossibilit`a di dichiarare membri dato, osserviamo che si possono dichiarare degli attributi di un’interfaccia, che sintatticamente sembrano membri dato, ma in realt`a servono solo a dichiarare implicita-mente dei membri funzione che leggono o assegnano valori. Sono, cio`e, un costrutto linguistico per mettere in evidenza un uso particolare di certi mem-bri funzione. Il compilatore IDL non genera alcuna istruzione per riservare memoria a tali pseudovariabili.

Il seguente esempio mostra l’interfaccia di un oggetto che gestisce un vet-tore i cui elementi sono sequenze di interi: la dimensione iniziale dell’oggetto pu`o essere un valore qualsiasi, fra zero e MAX SIZE, scelto dall’implementa-zione. La costante MAX SIZE viene resa disponibile ai clienti. Un cliente pu`o conoscere la dimensione e modificarla per mezzo delle operazioni, rispettiva-mente, get size() e resize(). Nell’esecuzione di alcune operazioni si pos-sono verificare le eccezioni SizeExc o RangeExc. I parametri delle operazioni sono in sola lettura, come specifica la parola chiave in.

interface Vector {

typedef sequence<long> VElem; exception SizeExc {};

exception RangeExc {};

const short MAX_SIZE = 3200; short get_size();

void resize(in short n) raises (SizeExc); VElem get_elem(in short n)

raises (RangeExc);

void set_elem(in short n, in VElem e) raises (RangeExc);

}

Si possono raggruppare pi´u interfacce, insieme a definizioni di tipo e di costanti, usando il costrutto module:

module Linear {

interface Vector { // ...