MokaByte 65 - Luglio Agosto 2002 
J2EE Patterns
Il pattern Business Delegate
di

S. Rossini
e L.Dozio

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

MokaByte® è un marchio registrato da MokaByte s.r.l. 
Java®, Jini® e tutti i nomi derivati sono marchi registrati da Sun Microsystems.
Tutti i diritti riservati. E' vietata la riproduzione anche parziale.
Per comunicazioni inviare una mail a info@mokabyte.it