MokaByte 63 - Maggio 2002 
J2EE Patterns Factory
II puntata: il pattern Factory
di
S. Rossini
e
L.Dozio

A cosa server questo pattern
La creazione di un oggetto prevede la conoscenza del/i costruttore/i della classe.
Il Factory fa parte della famiglia dei pattern che la letteratura indica come "creational" [GoF] e si utilizza per la creazione di istanze di classi attraverso un'interfaccia comune.
Il pattern è utilizzato ogni qualvolta si vuole disaccoppiare le modalità di creazione degli oggetti dal loro utilizzo.
I client sono resi indipendenti dalla creazione e dall'inizializzazione delle risorse mediante l'utilizzo di una classe Factory che incapsula la logica di costruzione (connessioni a resource pool, connessioni EIS, oggetti Dao , EJB, ecc…).
Questo approccio garantisce che un eventuale cambiamento della costruzione della classe concreta comporti modifiche alla sola classe Factory.
Funzionamento
La classe client fa riferimento alla classe Factory per ottenere l'oggetto d'interesse.
Di seguito si riporta il codice di un componente che richiede una classe che implementa il pattern Dao [Dao]:

import it.mokabyte.pattern.dao.MyDao;
import it.mokabyte.pattern.dao.MyDaoJdbcImpl;
import it.mokabyte.pattern.dao.MyDaoXmlImpl;

public void doSomething() {
  try {
    ...
    this.dao = new MyDaoJdbcImpl(<<Data Source>>);

oppure

    this.dao = new MyDaoXmlImpl(<<XML file>>);
  } catch (DAOException e) { . . . }
}

Per confronto si riporta il codice dell'EJB che questa volta richiede l'oggetto DAO utilizzando la classe Factory:

import it.mokabyte.pattern.dao.MyDaoFactory;
import it.mokabyte.pattern.dao.MyDao;

public void doSomething() {
  try {
    ...
    
this.dao = MyDaoFactory.getDAO();

oppure

  this.dao = MyDaoFactory.getDAO(<<DAO_TYPE>>);
  }
  catch (DAOException e) { . . . }
}

A parità di funzionalità offerte, applicando il pattern DAO Factory [J2EE] si guadagna in flessibilità e riusabilità rendendo indipendente l'EJB dalla specifica tipologia della classe DAO.
Struttura

Il DAO Factory viene invocato dal Business Object al fine di ottenere l'oggetto DAO.


Figura 1 - Sequence Diagram

Implementazione
Viene ora presentato un esempio di implementazione del DAO Factory.

 


Class Diagram (clicca per ingrandire)


L'EJB usa l'istanza DAO restituita dalla classe DaoFactory.

public void setEntityContext(EntityContext ctx) {
. . .
this.dao = MyDaoFactory.getDAO();
oppure
this.dao = MyDaoFactory.getDAO(<<DAO_TYPE>>);
. . .

Si noti che nel codice del bean non si fa riferimento a nessuna delle due classi concrete MyDaoJdbcImpl e MyDaoXmlImpl.
Il metodo getDao() restituisce la classe DAO concreta indicata dal valore della proprietà dell'envinroment entry
<<DAO_CLASS_NAME>>.

public class MyDaoFactory {

  public static MyDao getDAO() throws DAOException {
    MyDao dao = null;
    ...
    InitialContext ic = new InitialContext();
    String className = (String) ic.lookup(<<DAO_CLASS_NAME>>);
    dao = (MyDao) Class.forName(className).newInstance();
    ...
    return dao;
  }
}

Utilizzando il metodo getDao(<<DAO_TYPE>>) si può esplicitare la tipologia di DAO che si vuole utilizzare.

public static MyDao getDAO(int daoType) throws DAOException {
   MyDao dao = null;
  . . .
  switch(daoType) {
    case JDBC_TYPE :
      dao = new MyDaoJdbcImpl();
      break;
    case XML_TYPE :
      dao = new MyDaoXmlImpl();
      break;
  . . .

  return dao;
}

E' possibile utilizzare entrambi i DAO come riportato di seguito:

public void copyAccount(AccountPK key) throws XXXException {
  try{
    // Get DAO XML
    MyDao dao = MyDaoFactory.getDAO(DaoConfig.XML_TYPE);
    // Read Account from XML
    AccountOM obj = dao.readAccount(key);
    // Get DAO JDBC
    dao = MyDaoFactory.getDAO(DaoConfig.JDBC_TYPE);
    // Update Account to JDBC
    dao.updateAccount(key,obj);
  }
  
catch(DAOException daoe){. . .}
}


Un caso d'uso
Il caso d'uso proposto tratta il Factory di oggetti DAO. Si ha la possibilità di accedere a informazioni di conti correnti mediante le classi concrete MyDaoJdbcImpl (DBMS) e MyDaoXmlImpl (file XML).
L'EJB AccountBean utilizza il metodo getDao() per gestire il conto corrente o su DB o su XML.
L'EJB CopyBean legge un conto corrente da file XML e aggiorna il corrispondente su DB.

 

Allegati
L'esempio è scaricabile qui

 

Bibliografia e riferimenti
[Dao] S.Rossini, L. Dozio - "J2EE Patterns Dao", Mokabyte N.62 Aprile

[Gof] Gamma, Helm, Johnson, Vlissides :
Design Patterns - Elements of Reusable Object-Oriented Software
(ref. Abstract Factory /Factory Method)

[J2EE] Alur,Crupi,Malks :
Core J2EE Patterns - Best Practices and Design Strategies
(ref. Data Access Object)

[SunP] http://java.sun.com/j2ee/tutorial/index.htmll

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