|
Introduzione
Il business tier espone in rete i suoi servizi mediante
interfacce pubbliche.
Invocare direttamente i servizi di business dal client
causa un accoppiamento che porta a problematiche che
il client deve gestire.
A cosa serve
L'intento del pattern Business Delegate (BD) è
di disaccoppiare l'accesso ai servizi di business dai
client, nascondendo e centralizzando le operazioni di
localizzazione e utilizzo del servizio di business.
Il BD permette di avere i seguenti vantaggi :
-
fornire un'interfaccia uniforme ai client
- ridurre
l'accoppiamento tra presentation tier e business tier
- nascondere,
centralizzare e gestire le problematiche di reperimento
(lookup + create) e utilizzo dei componenti di business
- centralizzare
le modifiche derivanti da variazione dei servizi di
business in una sola classe
- ridurre
il numero di interazioni remote fra componenti in
comunicazione, con conseguente miglioramento di performance
- garantire
la possibilità di trasformare eccezioni tecnologiche
(es: java.rmi.RemoteException) in eccezioni applicative
- offrire
la possibilità di cache
Tutto
questo lo si ottiene realizzando una classe Java che
ha il compito di interfacciare il mondo di business
garantendo un'astrazione dei servizi al client.

Figura 1

Figura
2
Le
problematiche specifiche di lookup e narrow, potrebbero
essere gestite affiancando al BD una classe apposita
(pattern Service Locator - nel prossimo numero); in
questo caso il BD si occuperebbe "solo" di
gestire la logica di accesso al business tier.
Motivazione
L'approccio del pattern BD garantisce una separazione
netta fra l'invocazione del servizio sul presentation
tier e l'implementazione del servizio sul business tier.
Spiegazione del funzionamento
L'oggetto BD incapsula (e quindi maschera) al proprio
client le operazioni di lookup, narrow, create e di
invocazione dei metodi remoti dell'EJB agendo di fatto
da proxy [Remote Proxy - Gof] .
A titolo di esempio si riporta il codice di un client
che effettua un'invocazione ai servizi di business riferendosi
direttamente all'EJB Facade [Facade] :
import
javax.naming.* ;
import javax.rmi.PortableRemoteObject;
import java.rmi.RemoteException;
import javax.ejb.CreateException;
import it.mokabyte.pattern.ejb.session.stateful.FacadeHome;
import it.mokabyte.pattern.ejb.session.stateful.Facade;
public
class NoBusinessDelegateTestClient {
public void test(String userid) {
try {
Context ctx = new
InitialContext();
Object result =
ctx.lookup(JndiNames.FACADE);
FacadeHome home
=
(FacadeHome)PortableRemoteObject.narrow(result, FacadeHome.class);
Facade remote =
home.create(userid);
System.out.println("Amount
: " + remote.getAmount());
}
catch(NamingException ne) {
. . . }
catch(RemoteException re) {
. . . }
catch(CreateException ce) {
. . . }
A
parità di funzionalità offerte, l'utilizzo
del pattern Business Delegate semplifica il codice del
client nascondendo i dettagli di lookup, narrow e create
e di invocazione remota (gli import e le eccezioni sono
prettamente applicative) come mostrato di seguito:
import
it.mokabyte.pattern.delegate.MyBusinessDelegate;
import it.mokabyte.pattern.exception.BusinessDelegateException;
import it.mokabyte.pattern.valueobject.ProductOM;
public
class BusinessDelegateTestClient {
public void test(String userid) {
try {
MyBusinessDelegate
proxy = new MyBusinessDelegate("123");
System.out.println("Amount
: " + proxy.getAmount());
}
catch(BusinessDelegateException
bde) {
. . .
}
Struttura

Figura
3
Class
Diagram

Figura
4
Sequence
Diagram
Di
seguito si riporta un esempio di implementazione della
classe BD che agisce da "procuratore" nei
confronti di un EJB Facade :
- utilizzo
API JNDI per effettuare la lookup della Facade Home
interface
- utilizzo
della la Home Interface per creare l'EJB Facade
- invocazione
dei metodi di business dell'EJB
- rimozione
dell'EJB alla termine del suo utilizzo
Per
il compito svolto dai due pattern, esiste solitamente
un rapporto uno a uno fra le classi di BD e l'interfaccia
di Facade.
public
class MyBusinessDelegate {
/** Facade remote reference */
private Facade remote = null;
/** Constructor */
public MyBusinessDelegate(String user_id)
throws BusinessDelegateException {
try {
Context ctx = new InitialContext();
Object result = ctx.lookup(JndiNames.FACADE);
FacadeHome home =
(FacadeHome)PortableRemoteObject.narrow(result,
FacadeHome.class);
remote = home.create(user_id);
}
catch (Exception ex) {
ex.printStackTrace();
throw new BusinessDelegateException(ex);
}
}
/** get the amount */
public double getAmount() throws BusinessDelegateException
{
try {
return remote.getBalance();
// delegate to the EJB
} catch (RemoteException re) {
// wrap exception
re.printStackTrace();
throw new BusinessDelegateException(re);
}
}
Un
caso d'uso

Bibliografia e riferimenti
[Facade] S.Rossini, L. Dozio - "J2EE Patterns -
Il pattern facade", Mokabyte N.64 Giugno
[Gof]
Gamma, Helm, Johnson, Vlissides :
Design Patterns - Elements of Reusable Object-Oriented
Software
[J2EE]
Alur,Crupi,Malks :
Core J2EE Patterns - Best Practices and Design Strategies
[SJP]
Sun Java Center J2EE Patterns:
http://developer.java.sun.com/developer/restricted/patterns/J2EEPatternsAtAGlance.html
[BPP]
Sun blueprints-Design Patterns Catalog :
http://java.sun.com/blueprints/patterns/j2ee_patterns/catalog.html
|