Il linguaggio OMG IDL consente di:
// Struttura di una generica specifica IDL
module
nomeModulo {
//Dichiarazioni di costanti, tipi ed eccezioni a livello di modulo
<dichiarazioni di costanti>
< dichiarazioni di tipi>
<dichiarazioni di eccezioni>
//Dichiarazioni di interfacce
interface nomeInterfaccia1 [:<clausole_di_derivazione> ] {
//Dichiarazioni per l’interfaccia 1
<dichiarazioni di costanti>
<dichiarazioni di tipi>
<dichiarazioni di attributi>
<dichiarazioni di eccezioni>
//Dichiarazioni delle operazioni per l’interfaccia 1
[<tipo_di_ritorno] nomeOperazione1 (<parametri>)
[raises <eccezione>] [<contesto>]
[<tipo_di_ritorno>] nomeOperazioneN (<parametri>)
[raises <eccezione>] [<contesto>]
}; };
Un modulo IDL, introdotto dalla parola chiave module, permette di raggruppare in un’unica unità logica definizioni di:
In questo modo gli identificatori definiti all’interno di un modulo non possono entrare in conflitto con altri definiti in altri moduli. In altri termini, un modulo consente di definire uno spazio di nomi
// IDL – esempio di typedef
typedef string Data;
Introduce il nome di tipo Data, sinonimo di string
// IDL – esempio di tipo enumerativo
enum Colore {ROSSO, VERDE, BLU, GIALLO};
Introduce il nome di tipo Colore, e i suoi possibili valori
// IDL – esempio di struttura (tipo record)
struct DettagliPersonali { string nome; short eta; }
Introduce il tipo record d’utente DettagliPersonali
typedef struct DettagliPersonali_struct { // forma da evitare,
string nome; short eta; // introduce due nomi
} DettagliPersonali; // di tipo
Un’interfaccia IDL descrive le caratteristiche di un oggetto servente
L’interfaccia deve contenere le informazioni che un oggetto cliente deve conoscere.
Gli attributi non vanno pensati come dati dell’oggetto (né pubblici né privati)!
Le operazioni non vanno pensate come metodi pubblici!
// IDL – specifica dell’interfaccia del servizio S1
interface S1 {
// Proprieta’ di un oggetto S1
attribute float p1;
readonly attribute string p2;
// Operazioni definite su un oggetto S1
void op1(in float par1, out float par2, inout float par3);
void oneway op2(in any par1);
};
interface
Conto {
attribute float
saldo ;
readonly attribute string
proprietario;
void Deposito(in float
importo, out float
nuovoBilancio);
void Prelievo(in float
importo, out float
nuovoBilancio);
} ;
E’ possibile definire gerarchie di interfacce, mediante un meccanismo di ereditarietà, singola o multipla.
L’ereditarietà tra interfacce fornisce vantaggi significativi:
// IDL – esempio di interfaccia derivata
interface S2 : S1 {
exception Ex3 { string msg3; } ;
// Nuove operazioni definite per il servizio S2 derivato da S1
void oneway op3(in any par1) raises (Ex3);
};
// IDL – esempio di derivazione multipla tra interfacce
interface S3 : S1, S2 {
void oneway op4(in long par1); };
Concetti come la ridefinizione delle operazioni dell’interfaccia base da parte dell’interfaccia derivata, caratteristici dei linguaggi orientati agli oggetti, non hanno significato in IDL, che non riguarda l’implementazione degli oggetti.
Il codice di un’operazione viene (ri)definito quando l’interfaccia viene implementata in un linguaggio di programmazione.
Ne segue anche che un cliente progettato per invocare le operazioni dell’interfaccia base sarà anche in grado di invocare tali operazioni su un oggetto che implementa l’interfaccia derivata, che comprende le operazioni che il cliente si aspetta di trovare.
Il contrario non è vero: un cliente scritto per accedere all’interfaccia derivata non funzionerà su un oggetto dell’interfaccia base, in quanto potrebbe invocare operazioni aggiunte nell’interfaccia derivata.
Un’operazione può generare un’eccezione, per indicare che si è verificata una condizione anomala a tempo d’esecuzione.
Nella definizione dell’interfaccia in IDL, è necessario dichiarare i tipi delle eccezioni che possono essere generate e, per ciascuna operazione, elencare le eccezioni che può generare.
interface S1 { // IDL – esempio di interfaccia con eccezioni
attribute float p1;
readonly attribute string p2;
exception Ex1 {
string msg;
long val; };
exception Ex2 { string msg; } ;
void op1(in float par1, out float par2, inout float par3)
raises (Ex1, Ex2) };
Le eccezioni d’utente devono essere dichiarate nella lista raises:
Classificazione delle eccezioni
Le eccezioni di sistema devono essere dichiarate nella clausola raises:
Esempi di eccezioni standard di sistema
Un malfunzionamento viene generato o rilevato dall’ORB, che solleva una corrispondente eccezione di sistema e la inoltra al cliente.
Un malfunzionamento si genera nell’esecuzione del servente, che genera una eccezione che a sua volta viene inoltrata dall’ORB all’oggetto cliente
Generazione e gestione delle eccezioni da parte dell’ORB.
Introdotto nel linguaggio IDL, a partire dalla versione 2.3 dello standard CORBA.
Consente di definire oggetti, dotati di stato e di operazioni, da trasmettere come parametri di scambio nell’invocazione di metodi remoti, in modo che il ricevente possa operare localmente sull’oggetto stesso.
A tale scopo è prevista la parola chiave IDL valuetype.
La semantica dello scambio è per valore (object by value).
Una definizione valuetype comprende in generale:
Esempio
// IDL – esempio di valuetype
valuetype
Persona {
private
long stipendio; // stato
attribute
string nome; // attributi
void init(in string s); // operazioni
void incrementaStipendio(in short percentuale);
factory
create(in string s, in long n); // factory
};
2. La modellazione a oggetti e il linguaggio UML (richiami)
3. Generalità su Java e la programmazione ad oggetti
6. Regole di traduzione da UML a Java/C++
7. Programmazione multi-thread
8. Sincronizzazione tra thread
9. Programmazione client-server con socket TCP/IP (Java networkin...
10. Programmazione di applicazioni client-server: il Pattern Proxy...
12. Design Patterns
13. Pattern architetturali - Esempi
14. Design pattern creazionali. Esempi
15. Design pattern strutturali. Esempi
16. Introduzione alle tecnologie middleware
17. Modelli di middleware: RPC, MOM, TP, TS