MokaByte Numero 31  - giugno 1999
Il pattern Proxy
la pratica
di
Andrea Trentini
Incontriamo il Proxy. Una applicazione d'esempio.


Partiamo dal memento della puntata precedente e ne realizziamo una versione remotizzata.
Al solito, qui trovate il sorgente

L'abituale chiosa... ;-)

Visto che si è parlato di RMI mi piacerebbe schematizzarne la struttura con UML, in modo da averne una visione di insieme...
 


Qui vedete il Client che chiama un metodo su un oggetto remoto (RemoteObject), almeno è quello che CREDE di fare (user view)... ;-)
Nella realtà dell'implementazione il Client chiama il metodo su un oggetto che IMPLEMENTA LA STESSA INTERFACCIA DELL'OGGETTO REMOTO (ma che si trova nel suo stesso address space, cioè nella stessa JVM), l'oggetto RemoteObject_Stub (una delle due classi create dal compilatore rmic).
Tale stub comunica con uno skeleton (RemoteObject_Skel, l'altra classe creata da rmic) via socket (si passano degli oggetti di tipo Operation attraverso un ObjectStream) ed è proprio lo skeleton a chiamare il metodo sull'oggetto "remoto" (per lo skeleton l'oggetto "remoto" è in realtà locale, stanno sulla stessa JVM) e a ritrasmettere eventuali valori di ritorno al chiamante (seguendo la stessa strada: l'ObjectStream di prima). Chiaro no? ;-)
Un altro caso in cui incontriamo un proxy è quando usiamo le AWT. Ogni volta che creiamo un componente non "leggero" e lo rendiamo visibile viene creato il cosiddetto peer (provate a guardare la documentazione del metodo addNotify()). Il peer (o proxy) è l'oggetto NON java (quindi platform dependent) che noi vediamo come oggetto java e che usiamo come tale quando chiamiamo i suoi metodi. Ne esiste uno per ogni piattaforma su cui viene fatto girare java. Un Button avrà come peer un WindowsButton (non so se il nome è corretto ;-) sotto windows e un MotifButton (anche in questo caso non sono sicuro del nome ;-) sotto Unix.
 
 
 

Rendere "remoto" il memento

Ora torniamo pure alla nostra applicazione...
Se vi rammentate, nella puntata precedente avevo introdotto il concetto di Storage, un attore capace di... "gestire la memorizzazione da qualche parte (di solito su disco), a lui NON interessa da dove arrivano gli stati da salvare", tanto per citarmi. Questa volta vediamo l'esempio di un caretaker (l'attore che salva gli state) remoto, cioè una classe che incapsula le chiamate via RMI (trappando le eccezioni) e che quindi vi permette di trattare con uno Storage locale (che voi VEDETE come locale) ma che ridirige ogni sua funzionalità ad un VERO Storage istanziato su un'altra macchina.
La situazione è analoga a quella vista per lo schema del RMI, abbiamo un RemoteStorageClient che IMPLEMENTA la stessa interfaccia di uno Storage reale (entrambi implementano infatti StorageI).
RemoteStorageClient parla con RemoteStorageServer via RMI, ogni metodo dello Storage è replicato per delega prima dallo RemoteStorageServer (che infatti possiede un'istanza di StorageI) e poi anche dallo RemoteStorageClient, abbiamo quindi un doppio salto prima di arrivare allo Storage effettivo.

Avrei anche potuto saltare il doppio passaggio "client -> server -> storage" e remotizzare direttamente uno storage, ma avrei perso la possibilità (che ora invece sfrutto spesso ;-) di usare un RemoteStorageClient al posto di uno Storage qualsiasi, senza dover cambiare il sorgente di chi usa lo storage stesso (infatti avrei dovuto curare la cattura delle eccezioni ad ogni chiamata di metodo).
Guardate anche la gerarchia delle classi.
 
 

Come usare l'esempio

Scompattate lo zip (mantenendo la gerarchia) e avrete già tutto compilato e pronto da lanciare:
  • start rmiregistry
    • serve da portmapper, per sapere dove sono gli oggetti remoti
  • start java RemoteStorageServer
    • start è l'analogo della "&" in Unix
  • java RemoteStorageClient

  • Se invece volete ricompilare il sorgente perchè avete fatto modifiche... ;-)

  • javac *.java
  • rmic RemoteStorageServer
    • (per generare stub e skeleton)
Nella directory di nome "tmpStorage" verranno salvati gli state degli oggetti.
 

Alla prossima puntata

Spero di avervi interessato, come al solito vi esorto a farmi domande e commenti, sia direttamente
che su JAVA-IT.

MokaByte Java Web Magazine
www.mokabyte.it

La redazione di MokaByte ricerca nuovi collaboratori. 
Chi volesse mettersi in contatto con noi può farlo scrivendo a mokainfo@mokabyte.it