Design Pattern in Java: Proxy

Analizziamo un altro utile Design Pattern in java: il Proxy Pattern.

Il proxy pattern nasce principalmente per risolvere problematiche prestazionali legate all’accesso ad un oggetto che richiede tempi importanti per la creazione o semplicemente per essere raggiunto.

Il pattern prevede la realizzazione di un oggetto proxy che viene usato al posto dell’oggetto reale e che quindi deve avere necessariamente la stessa “forma” dell’oggetto che sostituisce. Il proxy poi si preoccuperà di contattare l’oggetto reale, nella modalità e nel momento più opportuni.Approfondiamo la questione esaminando un esempio.

Si ha la necessità di sviluppare un oggetto ImageHandler che permetta di ricavare diverse informazioni da un file immagine. In particolare la classe deve essere in grado di fornire le dimensioni dell’immagine, espresse in pixel, attraverso i metodi getWidth() e getHeight(), di fornire il valore di un determinato pixel, attraverso il metodo getPixel(int x, int y) che richiede come parametri le coordinate del pixel e attraverso il metodo getContent() fornisca l’intera immagine come array di bytes.
Infine il metodo getFileName() restituisce il nome del file immagine come stringa.
Supponiamo che l’accesso alle immagini in questione sia alquanto dispendioso in termini di tempo, magari perchè molto distanti.  E’ evidente che l’apertura del file solo per conoscerne un pixel è inutilmente costoso, specie se spesso viene richiesto sempre lo stesso sottoinsieme di pixels. In tal caso l’oggetto ProxyImageHandler fungerà da caché proxy, immagazzinando i pixel di cui si conosce già il valore, per un precedente accesso e restituendo tali valori senza dover aprire nuovamente il file immagine.
Per alcune operazioni poi, come getFileName(), non è necessario istanziare l’oggetto reale, caricando l’immagine e perdendo inutilmente tempo. In questi casi il proxy funge da virtual proxy posponendo l’istanzazione del RealSubject a quando realmente indispensabile.

ImageHandler

 

Esaminiamo il diagramma sopra, in dettaglio. ProxyImageHandler e RealImageHandler devono avere, come dicevamo, la stessa forma, per questo implementano la stessa Interfaccia(Subject): ImageHandler.
Il Proxy quindi gestisce l’accesso al RealSubject, in questo caso RealImageHandler, secondo politiche di ottimizzazione e lo sostiutuisce completamente alla vista degli utilizzatori.
Dal punto di vista dell’implementazione del codice, la cosa è abbastanza semplice. Si scrive la classe che rappresenta l’interfaccia Subject, che entrambi gli oggetti devono estendere:

Il RealSubject, in questo esempio RealImageHandler, estenderà il Subject e implementerà la logica di caricamento dell’immagine direttamente nel costruttore. I vari metodi, accedendo direttamente all’oggetto immagine restituiranno i valori richiesti (altezza, larghezza, valore di un pixel).

Anche il Proxy, dovendo sostituire in tutto il RealSubject, deve estendere la classe Subject e soprattutto mantenere una istanza del RealSubject, che pero’ non viene creata solo al momento in cui diventa indispensabile caricare in memoria il contenuto del file, quindi quando si richiede l’intero contenuto o il valore di un singolo byte.

Gli scenari di applicazione di questo pattern sono vari. Ad esempio RMI (Remote Method Invocation) che utilizza il Proxy Pattern per l’interfacciamento ad oggetti remoti. In questo caso le classi Proxy sono dette “stub”.
Un altro campo di applicazione classico di questo pattern è la sicurezza. Il Security Proxy o Protection Proxy puo’ sostituirsi a sistemi “legacy” che non abbiano una adeguata politica di sicurezza, per evitare che l’utilizzatore acceda direttamente ad essi e implementando lo strato di protezione necessaria.

 

Lascia un commento

Il tuo indirizzo email non sarà pubblicato. I campi obbligatori sono contrassegnati *