RMI
e la programmazione per pattern
L’estrema
semplicità con cui è possibile realizzare applicazioni distribuite
in Java, permette sicuramente di semplificare enormemente il lavoro, ma
spesso si dimostra essere anche la sua principale limitazione.
Alcune
delle limitazioni imposte dal modello alla base di RMI possono essere superate
in maniera piuttosto brillante grazie ad una opportuna progettazione della
struttura delle classi che compongono lo scheletro dell’applicazione. In
particolare la programmazione per pattern ([GOF] [java pattern] [mokabyte
pattern]), permette di dar vita ad interessanti soluzioni, e proprio per
questo saranno presi in esame due pattern particolarmente utili, il Factory
Method ed il Command.
RMI ed il Pattern
Factory
Se
si ripensa per un momento alla modalità di pubblicazione di un oggetto
remoto da parte del server RMI, si potrà osservare come la funzione
di creazione e registrazione è un compito totalmente a carico del
server
Per
una precisa scelta progettuale quindi, visto che la registrazione dell’oggetto
avviene una volta sola, l’istanza dell’oggetto remoto sarà l’unica
disponibile e quindi condivisa fra tutti i client possibili.
Pensata
per la massima semplicità possibile, in molti casi però questa
soluzione risulta essere troppo rigida e non sufficiente per creare strutture
distribuite complesse.
Si
pensi ad esempio a tali oggetti come a veri e propri servizi messi a disposizione
dal server, accessibili dal client proprio perché oggetti remoti,
e per questo per brevità verranno qui chiamati “oggetti remoti di
servizio”.
Per
rendere tali oggetti pubblici ed invocabili da un client RMI, si potrebbe
pensare di crearne un certo numero, e successivamente di registrarli
nel registro remoto con nomi differenti.
Ovviamente
tale soluzione non risolve il problema della condivisione fra i vari client,
dato che per tanti che possano essere gli oggetti remoti di servizio
registrati, i client potrebbero essere in numero maggiore; inoltre
tale organizzazione non risolve il problema della creazione on-demand da
parte del client.
Sebbene
il modello teorico di RMI non prevede, almeno per il momento, una soluzione
a tale limitazione, grazie all’utilizzo di un particolare schema
progettuale, il pattern factory appunto, vi si può ovviare
in modo piuttosto semplice.
Si
supponga ad esempio di avere una insieme base di oggetti strutturati come
riportato in figura 1.
Si
tratta di una semplice gerarchia di classi per la gestione dei messaggi
di log all’interno di una applicazione: per semplicità verrà
preso in considerazione il caso in cui sia presente il solo metodo log(String
messaggio) per la produzione di tali messaggi.
La
classe base (Logger) quindi serve per gestire messaggi di tipo generico,
mentre le due derivate potrebbero implementare tecniche particolari per
la gestione di messaggi verso file (classe FileLogger) e verso uno stream
generico (classe StreamLogger)
Figura
1 struttura gerarchica di base per la gestione di messaggi di
log
A tal
punto si può immaginare che un ipotetico client possa aver bisogno
di utilizzare i servizi di un oggetto di tipo FileLogger oppure
StreamLogger, ad esempio per memorizzare alcune informazioni relative
al suo funzionamento.
Si
potrebbe quindi ipotizzare che ogni client debba o voglia poter produrre
messaggi propri indipendentemente dagli altri, e che tali messaggi siano
gestiti da un server centrale.
Utilizzando
RMI allora si dovrà per prima cosa creare n oggetti remoti (in teoria
uno per ogni client che desideri fare log da remoto) e successivamente
registrarli.
Per
rendere remoti gli oggetti visti in precedenza è necessario modificare
leggermente la gerarchia di classi, cosa che può portare ad una
organizzazione delle classi come quella riportata in figura 2
Figura
2 Versione remota delle classi per la
gestione
dei messaggi da client RMI
Come
si può notare, la classe base è stata sostituita dalla interfaccia
remota RemoteLogger, la quale, oltre a sopperire alla funzione di interfaccia
standard, permette alle sotto classi di essere oggetti remoti a tutti gli
effetti.
Si
è predisposta in tal modo la base per permettere l’utilizzo da client
RMI di oggetti remoti.
A
questo punto si deve predisporre un qualche meccanismo che permetta
la creazione di tali oggetti anche da parte di client RMI.
La
classe LoggerFactory che implementa il cosiddetto pattern factory, è
a tutti gli effetti un oggetto remoto come quelli visti in precedenza:
tramite la sua registrazione nel registro RMI, ogni client potrà
ottenerne lo stub ed invocarne il metodo remoto getLogger(), la cui implementazione
è riportata di seguito
public
RemoteLogger getLogger(int type) throws RemoteException{
RemoteLogger ret=null;
if (type == 1){
ret= new RemoteFileLogger();
}
if (type == 2){
ret= new RemoteStreamLogger();
}
return ret;
}
Come
si può notare tale metodo controllando il valore del parametro passato,
è in grado di restituire un oggetto (remoto) di tipo FileLogger
e StreamLogger; più precisamente viene restituita una interfaccia
remota Logger, cosa che permette di mantenere la massima genericità
possibile.
Da
un punto di vista organizzativo le classi remote che implementano il factory
sono strutturate secondo lo schema UML riportato in figura 3
Figura
6 Il factory remoto
Il
client invocando il metodo remoto getLogger() riceverà lo stub dell’oggetto
remoto, il quale verrà eseguito sul server remoto, in perfetto accordo
con il modello teorico di RMI.
Conclusioni
Come
si è potuto vedere, grazie all'utilizzo di un semplice patter come
il Factory, si è potuto implementare una soluzione molto semplice
per superare alcune limitazioni imposte dalla architettura di RMI. Si tenga
presente che pur senza effettuare nessuna modifica al modello teorico di
RMI, si è ottenuto un comportamento fortemente diverso da quello
base. Per chi volesse approfondire ulteriormente la programmazione dei
pattern si consiglia la lettura di [1], e sopratutto del corso iniziato
su MB nel numero 26, di Gennaio 1999.
Bibliografia
[1]
- "Java Design Patterns A Tutorial" di James William Cooper,
James W. Cooper
Ed.
Addison-Wesley Pub CoI ISBN 0201485397
[2]
- "Distributed Programming With Java " di Qusay H. Mahmoud - Ed. Manning
Publications Company ISBN: 1884777651
|