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
|