Vous êtes sur la page 1sur 9

Quelques patterns Ce cours prsente des modles de

pour la persistance des objets conception que lon peut utiliser pour
effectuer la persistance des objets avec le
avec DAO modle de conception DAO

Universit de Nice Sophia-Antipolis


Version 0.9.4 18/4/06
Richard Grin

R. Grin Mapping objet-relationnel page 2

DTO
Un Data Transfert Object (DTO) contient ltat
dun (ou de plusieurs) objet mtier, mais pas
son comportement
Le modle de conception DTO Ce modle de conception est utilis pour

(Data Transfert Object) transporter ltat dun objet entre 2 couches


distantes (sur 2 machines distinctes) dans une
application distribue
Synonyme : Transfert Object (TO)
Il faut viter les DTOs si lapplication est
locale (complique inutilement)
R. Grin Mapping objet-relationnel page 3 R. Grin Mapping objet-relationnel page 4

Un fait important Le problme rsoudre


Les appels de mthode distants sont Un client souhaite rcuprer des donnes en
beaucoup plus coteux que les appels locaux interrogeant un ou plusieurs objets distants
Le cot dpend peu de la quantit de Exemple : rcuprer les nom, prnom, salaire
donnes transfre entre les JVMs chaque et lieu de travail dun employ
connexion distante : ramener un lot Sil utilise les accesseurs des classes des
dinformation en 2 appels de mthode est objets (getNom, getPrenom, getSalaire,
beaucoup plus coteux que de le ramener en getLieu), plusieurs appels distants (donc
un seul appel coteux) sont ncessaires

R. Grin Mapping objet-relationnel page 5 R. Grin Mapping objet-relationnel page 6

1
La solution
Le client demande un DTO qui contient
toutes les valeurs dont il a besoin
Cet objet est construit sur le site distant et
pass en une seule fois au client
Le modle de conception DAO
Les DTO peuvent aussi tre utiliss pour (Data Access Object)
modifier les proprits des objets distants

R. Grin Mapping objet-relationnel page 7 R. Grin Mapping objet-relationnel page 8

DAO DAO
Le modle de conception DAO permet disoler La persistance est dlgue des objets
le code li la persistance des donnes ddis, appels DAO
Quand lapplication a besoin deffectuer une
Sans doute le modle de conception le plus
utilis dans le monde de la persistance opration lie la persistance dun objet, elle
fait appel un objet DAO qui elle passe les
informations ncessaires pour effectuer
lopration
Chaque classe dobjet mtier a son propre
type de DAO
Mais le mme objet DAO est utilis pour tous
les objets dune classe dobjet mtier
R. Grin Mapping objet-relationnel page 9 R. Grin Mapping objet-relationnel page 10

Le problme rsoudre La solution


Le code pour la persistance varie beaucoup Encapsuler la persistance des donnes dans des
n avec le type de stockage (bases de objets DAO dont linterface est indpendante du
donnes relationnelles, bases de donnes support de la persistance
orientes objet, fichiers simples, etc.) Linterface entre les DAO et le reste de
n avec les implmentations des fournisseurs lapplication ne doit pas varier si on change de
de logiciels de stockage source de donnes
Si les ordres de persistance sont imbriqus
avec le code mtier , il est difficile de
changer de source de donnes

R. Grin Mapping objet-relationnel page 11 R. Grin Mapping objet-relationnel page 12

2
CRUD CRUD : oprations de base des DAOs
Cet acronyme, souvent utilis dans le monde de
la persistance, dsigne les 4 oprations de base Create pour crer une nouvelle entit dans la
de la persistance qui sont implmentes dans un base
DAO : create, retrieve, update et delete Retrieve pour retrouver une ou plusieurs
Les DAO conservent ltat des objets persistants entits de la base
(dans leurs variables dinstance) et le reste de Update pour modifier une des entits de la
lapplication utilise ces mthodes pour grer la base
persistance de ces objets Delete pour supprimer une entit de la base
Les DAO peuvent aussi grer les Plusieurs variantes pour les signatures de
connexions/dconnexions la source de ces mthodes dans les DAOs
donnes
R. Grin Mapping objet-relationnel page 13 R. Grin Mapping objet-relationnel page 14

Emplacement des DAOs create


Prend en paramtre ltat de la nouvelle entit
Les DAOs sont placs dans la couche dite Cet tat peut tre donn
daccs aux donnes qui est souvent sur
n par une srie de paramtres des types des
une autre machine que la couche des objets
donnes : create(int id, String nom,)
mtiers
n par un DTO
Les changes de messages entre les DAOs
n par lobjet mtier que lon veut rendre
et les objets mtiers engendrent donc
souvent des appels distants et des DTO persistant : create(Article article)
peuvent donc tre utiliss pour amliorer la La 1re variante est sans doute la plus
vitesse des changes frquemment utilise et la plus souple
La 2me est trs utilise avec les EJB

R. Grin Mapping objet-relationnel page 15 R. Grin Mapping objet-relationnel page 16

create create
La dernire variante ne convient que si lobjet Le type retour peut tre
mtier a toutes ses proprits publiques et sil
n void (la variante la plus utilise)
est transportable si cest un objet distant
n boolean, pour indiquer si la cration a pu
Elle augmente la dpendance de la couche de
avoir lieu
persistance vis--vis de la couche logique, ce
n un identificateur de lentit ajoute
qui est plutt ngatif
n un objet mtier correspondant lentit
De plus elle nest pas vraiment adapte aux
modles objet avec des hirarchies dhritage ajoute
complexes La variante avec objet mtier a les mmes
Cependant cette variante peut tre pratique et inconvnients (et avantages) que pour le
performante dans les cas o elle est applicable passage de paramtre dun objet mtier
R. Grin Mapping objet-relationnel page 17 R. Grin Mapping objet-relationnel page 18

3
retrieve Finder qui retourne un objet
3 types de finder suivant quil retourne On lui passe en paramtre un identificateur
n un seul objet de lentit cherche
n une collection dobjets Il retourne un objet mtier qui correspond
n une valeur calcule partir de plusieurs lentit cherche, ou un DTO qui contient les
entits (agrgation) donnes de lentit cherche

R. Grin Mapping objet-relationnel page 19 R. Grin Mapping objet-relationnel page 20

Finder qui retourne une collection Finder qui retourne une valeur
On lui passe en paramtre le critre de
slection, sous une forme quelconque Les valeurs calcules partir des donnes
de plusieurs entits (exemple : total des
n objet ou valeurs critre de slection
salaires) peuvent sobtenir partir dobjets
n objet exemple
chargs en mmoire
Le type retour peut tre trs divers :
Mais il peut tre prfrable de ne pas crer
n ResultSet les objets et dinterroger directement la base
n RowSet de donnes qui est optimise pour ce type de
n Collection (Collection, List, Set,) requte
dobjets mtier ou de DTOs Un DAO peut ainsi comporter une mthode
n tableau (rare) qui renvoie le total des salaires des employs
R. Grin Mapping objet-relationnel page 21 R. Grin Mapping objet-relationnel page 22

update delete
Des variantes diverses pour les paramtres :
n identificateur + valeurs (plusieurs Pour les paramtres :
paramtres pour les valeurs ou un seul n identificateur de lentit supprimer dans
DTO) la base
n lobjet mtier dont on veut sauvegarder les n lobjet mtier correspondant lentit
modifications (ncessite un accs public supprimer dans la base
aux valeurs qui seront modifies)
Pour le type retour :
Le type retour peut tre
n void
n void
n boolean pour indiquer si la suppression a
n boolean pour indiquer si la modification a
pu avoir lieu pu avoir lieu

R. Grin Mapping objet-relationnel page 23 R. Grin Mapping objet-relationnel page 24

4
DAO et exceptions DAO et exceptions
Les mthodes des DAO peuvent lancer des Pour cela, on cre une ou plusieurs classes
exceptions puisquelles effectuent des dexception indpendantes du support de
oprations dentres-sorties persistance, dsignons-les par DAException
Les exceptions ne doivent pas tre lies un (ou DataAccessException ou
type de DAO particulier si on veut pouvoir DaoException)
changer facilement de type de DAO Les mthodes des DAO attrapent les exceptions
particulires, par exemple les SQLException,
et relancent des DAException (auxquels sont
chanes les exceptions dorigine pour faciliter la
mise au point)
R. Grin Mapping objet-relationnel page 25 R. Grin Mapping objet-relationnel page 26

2 stratgies dutilisation des DAOs Stratgie 1


1. Chaque objet mtier a une rfrence son Les programmes qui manipulent les objets
DAO et lutilise pour sa propre persistance. mtier ne sont pas modifis par rapport un
Le programme qui manipule les objets programme qui nutilise pas de DAO
mtier ne connat pas les DAOs. Seuls les objets mtier connaissent leur DAO
2. Le programme qui manipule les objets Les objets mtier doivent avoir une rfrence
mtier utilise directement les DAOs. vers le DAO qui leur correspond
Les objets mtier nont pas de rfrence Cette rfrence peut tre obtenue par une
un DAO. mthode static de la classe DAO (ce qui
(stratgie sans doute la plus frquemment peut permettre de partager un DAO entre tous
utilise) les objets mtier dune mme classe)
R. Grin Mapping objet-relationnel page 27 R. Grin Mapping objet-relationnel page 28

Exemple de code Stratgie 2


class Stylo {
private StyloDAO dao; On rencontre le plus souvent la stratgie 2
... on peut aussi On perd sans doute de la puret de la
public void sauvegardeToi() { construire un
dao = getDAO();
programmation objet
TO pour le
dao.insertOrUpdate(this); passer au DAO
}
private StyloDAO getDAO() {
if (dao == null)
Pour simplifier, on ne
StyloDAO.getDAO();
tient pas compte des
return dao;
exceptions
}

R. Grin Mapping objet-relationnel page 29 R. Grin Mapping objet-relationnel page 30

5
Exemple de code Diagramme de classes (avec
utilisation de TO)
// ou styloDAO = new StyloDAO()
StyloDAO styloDAO = StyloDAO.getDAO();
Stylo stylo =
styloDAO.create(145, "Marker",
TO ou objet "noir ", 120,...);
. . . mtier
Stylo stylo = styloDAO.findById(1234);
stylo.setPrix(250);
styloDAO.update(stylo);
Cette image (et les suivantes) sont extraites du
List l = styloDAO.findAll(); Core J2EE Pattern Catalog de Sun

R. Grin Mapping objet-relationnel page 31 R. Grin Mapping objet-relationnel page 32

Diagramme de squences
DAO et connexions
Le plus souvent une connexion est ouverte
au dbut des mthodes du DAO, et ferme
la fin des mthodes
Cette stratgie peut coter cher si un pool de
connexions nest pas utilis
Le DAO peut aussi contenir des mthodes
pour ouvrir et fermer une connexion ; en ce
cas, une connexion peut tre utilise par
plusieurs mthodes du DAO

R. Grin Mapping objet-relationnel page 33 R. Grin Mapping objet-relationnel page 34

DAO et transactions Transactions gres par le client


Le client peut grer les transactions dans le
Le plus souvent le DAO dmarre et termine
cas dune application qui utilise JDBC, sans
lui-mme les transactions
serveur dapplications, en lanant les
Dans les cas complexes, plusieurs DAO mthodes commit() ou rollback() de la
associs plusieurs types dobjets mtier classe Connection
peuvent intervenir dans une transaction Pour cela, il utilise linstance de Connection
Dans ce cas, cest le client qui va grer les renvoye par la mthode du DAO qui ouvre
transactions une connexion (ou par une mthode
Avec JDBC, a implique que les connexions getConnection() du DAO)
ne sont pas ouvertes et fermes pour chaque Avec les serveurs dapplications, il existe des
mthode ; JTA na pas cette limitation mthodes pour obtenir la transaction en cours
R. Grin Mapping objet-relationnel page 35 R. Grin Mapping objet-relationnel page 36

6
DAO et hritage DAO et hritage
La solution est de crer une hirarchie
Le problme : une classe a des classes parallle de classes mappers dont les
mres qui ont des proprits persistantes qui instances contiendront les mmes donnes
ne sont pas visibles de lextrieur (private, que la hirarchie de la classe dont le DAO
sans accesseurs visibles) gre la persistance (voir le pattern
Comment le DAO va pouvoir grer la Inheritance Mappers dans le livre de
persistance des instances de cette classe ? Martin Fowler donn dans la bibliographie)
Chacune des classes mappers se charge des
donnes qui la concerne pour fournir au DAO
les donnes ncessaires aux changes avec
la base de donnes
R. Grin Mapping objet-relationnel page 37 R. Grin Mapping objet-relationnel page 38

Patterns pour rcuprer les DAO


Comment associer le bon DAO chaque
classe mtier ?
Si on change de SGBD, on doit changer de
Le modle de conception type de DAO
fabrique abstraite Le pattern fabrique (factory) convient bien
pour ce genre de problme car il permet de
cacher le type concret de la classe dune
instance que lon cre (ce qui facilite le
changement de ce type concret)

R. Grin Mapping objet-relationnel page 39 R. Grin Mapping objet-relationnel page 40

Fabrique abstraite Fabrique abstraite


Le pattern fabrique abstraite permet de Une fabrique abstraite est un type abstrait qui
changer facilement de source de donnes permet de cacher les types rels dun
En une seule ligne de code tous les DAO ensemble de fabriques concrtes
peuvent tre remplacs par des DAOs Chaque fabrique concrte fournit tous les
adapts la nouvelle source DAOs (DAOStylo, DAORamette,) associs
une certaine source de donnes
Dans la ligne de code, on rcupre la bonne
fabrique de DAOs, associe la bonne
source de donnes

R. Grin Mapping objet-relationnel page 41 R. Grin Mapping objet-relationnel page 42

7
Le type
abstrait Code client (dbut) Code client (suite)
DAOFactory daoFactory = La ligne de code pour
// Supprime un stylo de la base
DAOFactory.getDAOFactory( changer de SGBD
styloDAO.delete(styloNo);
DAOFactory.TypeDao.MYSQL);
styloDAO = daoFactory.getStyloDAO(); // Trouve tous les stylos dune marque
// cre un nouveau stylo dans la base StyloTO styloEx = new StyloTO();
int styloNo = styloDAO.insert(...); styloEx.setMarque("Marker");
// Trouve un stylo Collection listeStylos =
StyloTO styloTO = styloDAO.find(...); styloDAO.selectTO(styloEx);
// Modifie des valeurs du TO
styloTO.setPrix(125); ...
// Modifie le stylo dans la base
styloDAO.update(styloTO);

R. Grin Mapping objet-relationnel page 43 R. Grin Mapping objet-relationnel page 44

Fabrique abstraite 1 DAO Fabrique abstraite 1 source de donnes


La fabrique
abstraite

Les fabriques Une fabrique concrte


concrtes cre tous les DAOs
associs une source
de donnes

Les DAOs
crs

R. Grin Mapping objet-relationnel page 45 R. Grin Mapping objet-relationnel page 46

Fabrique abstraite schma global Code pour fabrique abstraite


Le code qui suit est un exemple schmatique
de lutilisation du pattern DAO, avec le pattern
fabrique abstraite (inspir fortement dun
exemple donn par Sun)
Il utilise aussi le pattern TO
Important : ce pattern TO peut tre vit si les
objets persistants peuvent tre transports
entre les diffrentes couches dune
application (par exemple, pour une
application locale, ou en utilisant les objets
dtachs de Hibernate)
R. Grin Mapping objet-relationnel page 47 R. Grin Mapping objet-relationnel page 48

8
La fabrique abstraite Une fabrique concrte
public abstract class DAOFactory {
public enum TypeDao {MYSQL, ORACLE}; public class MySQLDAOFactory
public abstract StyloDAO getStyloDAO(); extends DAOFactory {
public abstract FactureDAO getFactureDAO(); @Override
... public StyloDAO getStyloDAO() {
public static
return new MySQLStyloDAO();
DAOFactory getDAOFactory(TypeDao typeDao) {
switch (typeFabrique) { }
case MYSQL: return new MysqlDAOFactory(); @Override
case ORACLE: return new OracleDAOFactory(); public FactureDAO getFactureDAO() {
default: ... ; // erreur return new MySQLFactureDAO(); }
}
...
}
} }
R. Grin Mapping objet-relationnel page 49 R. Grin Mapping objet-relationnel page 50

Interface des DAO pour Stylo DAO concret pour Stylo


public interface StyloDAO { import java.sql.*;
public int insert(...); public class MySQLStyloDAO
public boolean delete(...); implements StyloDAO {
public StyloTO find(...); public MySQLStyloDAO() { ... }
public boolean update(...); public int insert() { ... }
public boolean delete() { ... }
public RowSet selectRS(...);
public StyloTO find() { ... }
public Collection selectTO(...);
...
...
}
}

R. Grin Mapping objet-relationnel page 51 R. Grin Mapping objet-relationnel page 52

TO pour Stylo Bibliographie


import java.io.Serializable;
Patterns of Entreprise Application
public class StyloTO implements Serializable {
Architecture de Martin Fowler Addison
private String reference;
Wesley
private String name;
... Prsentation du pattern DAO et

// Accesseurs et modificateurs implmentation en Java, par Sun :


public String getReference() {...}
http://java.sun.com/blueprints/corej2eepattern
public void setReference(String ref) {...}
s/Patterns/DataAccessObject.html
...
}

R. Grin Mapping objet-relationnel page 53 R. Grin Mapping objet-relationnel page 54