Home   |   Archivio   |   Chi siamo   |   Contatti
Stefano Rossini & Luca Dozio
Il Pattern Value Object
Il Pattern Value Object
di
Stefano Rossini & Luca Dozio
Introduzione Contesto Le applicazioni client necessitano scambio di dati con i business objects.

Introduzione

Contesto Le applicazioni client necessitano scambio di dati con i business objects.

A cosa serve Intento L’intento del pattern è di modellare i dati di business in modo granulare mediante oggetti: i ValueObject. I Value Object incapsulano la quantità di business data necessaria per soddisfare le esigenze del client nel colloquio con l’EJB. In questo modo si ottiene una visione ad oggetti dei dati di business ottimizzando il trasferimento remoto dei dati. Motivazione Come ogni pattern ci sono diverse strategie:

  • Oggetti immutabili (i suoi campi sono solo read-only, cioè solo metodi get) - Value Objects Strategy
  • Business objects che rappresentano strutture dati (metodi get/set) - Updatable Value Objects Strategy
  • Aggregazione di diversi oggetti immutabili – Multiple Value Object Strategy
  • Aggregazione di oggetti immutabili reperiti da differenti data store - Value Object Assembler Strategy

Spiegazione del funzionamento Si crea e si utilizza un Ejb, sul quale vengono invocati i metodi per reperire i dati di business.

public class FacadeTestClient {

    . . .
    public void test(String userid) {

        Context ctx = new InitialContext();

        Object obj = ctx.lookup(JndiNames.FACADE);

        FacadeHome facadeHome = (FacadeHome)PortableRemoteObject.narrow(obj,
            FacadeHome.class);

        Facade facade = facadeHome.create(userid);

        System.out.println("User account name    : " + facade.getName());

        System.out.println("User account email   : " + facade.getEmail());

        System.out.println("User account balance : " + facade.getBalance());

A parità di funzionalità offerte, l’utilizzo del pattern Value Object richiede una sola invocazione remota all’EJB:

public class FacadeObjectValueTestClient {

    . . .
    public void test(String userid) {

        Context ctx = new InitialContext();

        Object obj = ctx.lookup(JndiNames.FACADE);

        FacadeHome facadeHome = (FacadeHome)PortableRemoteObject.narrow(obj,
            FacadeHome.class);

        Facade facade = facadeHome.create(userid);

        AccountVO objectValue = facade.getAccount();

        System.out.println("User account name    : " + objectValue.getName());

        System.out.println("User account email   : " + objectValue.getEmail());

        System.out.println("User account balance : " +
                        objectValue.getBalance());

Usando accorgimenti di programmazione come il Value Object si ottimizza il trasferimento delle informazioni al client evitando di fare viaggiare singolarmente i dati applicativi (nell’esempio sono i dati name, email e balance).

##

<<INSERIRE QUI IMMAGINE 1>>

<<INSERIRE QUI IMMAGINE 1>>

Funzionamento senza ValueObject

##

<<INSERIRE QUI IMMAGINE 2>>

<<INSERIRE QUI IMMAGINE 2>>

Funzionamento con ValueObject

Struttura

##

<<INSERIRE QUI IMMAGINE 3>>

<<INSERIRE QUI IMMAGINE 3>>

Class Diagram

Un caso d'uso

L’EJB Facade presentato in [FACADE] piuttosto che restituire i singoli dati dell’Entity Bean Account

public class FacadeBean implements SessionBean {
/** Remote reference to the Entity EJB Account */
private Account account = null;

. . .
// <<property name>> è il nome della proprietà dell’Entity EJB (name, email,
// balance)
public double get << property name>> () {

    try {

        return account.get << property name>>();

    } catch(java.rmi.RemoteException e) {

        throw new
            BusinessException("Exception reading property <<property name>>  : "
                        +
                        e);

    }

}

mette a disposizione un metodo di business che crea un Value Object, lo popola “accorpando” i dati prelevati dall’Entity e lo restituisce:

public class FacadeBean implements SessionBean {
/** Remote reference to the Entity EJB Account */
private Account account = null;

. . .
public AccountVO getAccount() throws BusinessException {

    try {

        AccountVO objectValue = new AccountVO(this.account.getName(),
                        this.account.getEmail(),
                        this.account.getBalance());

        return objectValue;

    } catch(java.rmi.RemoteException e) {

        throw new BusinessException("FacadeBean getBalance() failed: " + e);

    }

}

Il Value Object è costituito dalla classe AccountVO, che è una classe Java serializzabile con gli opportuni metodi get:

public class AccountVO implements java.io.Serializable {
private String name = null;

private String address = null;

private double balance = 0.0;

public AccountVO(String nm, String add, double bal) {

    this.name = nm;

    this.address = add;

    this.balance = bal;

}

// Accessors
public String getName() {
    return this.name;
}

public String getAddress() {
    return this.address;
}

public double getBalance() {
    this.balance;
}

}

Il trasferimento dati tra l’EJB Facade e l’Entity Account può essere ulteriormente ottimizzato applicando nuovamente il pattern Value Object analogamente a quanto fatto per la comunicazione tra client e EJB Facade. L’Entity Account espone un nuovo metodo getAccount() che restituisce un Value Object AccountVO.

public class AccountBean implements EntityBean {

    private double balance;

    private String name;

    private String email;

    . . .
    public AccountVO getAccount() {

        AccountVO objectValue = new AccountVO(id, this.name, this.email,
                        this.balance);

        return objectValue;

    }

In questo modo il Facade EJB non invoca piu’ i metodi getName(), getEmail() e getBalance(), bensì il solo metodo getAccount():

public class FacadeBean implements SessionBean {

    private Account account = null;

    . . .
    public AccountVO getAccount() throws BusinessException {

        try {

            return this.account.getAccount();

            . . .

##

<<INSERIRE QUI IMMAGINE 4>>

<<INSERIRE QUI IMMAGINE 4>>

Allegati

L’esempio è scaricabile qui

<< METTERE LINK A ESEMPI_VALUEOBJECT.ZIP >>

L’esempio è scaricabile qui << METTERE LINK A ESEMPI_VALUEOBJECT.ZIP >>

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

PAGE

PAGE1

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