Faisons le topo de ce que nous avons :
- des objets métiers ;
- une implémentation d'accès aux données ;
- une classe permettant d'instancier les objets d'accès aux données.
Le fait est que notre structure actuelle fonctionne pour notre système actuel... Ah ! Mais ! Qu'entends-je, qu'ouïe-je ?
Votre patron vient de trancher ! Vous allez utiliser PostgreSQL ET du XML !
C'est bien ce qu'on disait plus haut... Comment gérer ça ?
On ne va pas mettre des if(){...}else{} dans la fabrique, tout de même ?
Ah ! Je vous arrête !
Vous entendez ce que vous dites :
Citation : Les ZérOsOn ne va pas mettre des if(){...}else{} dans la fabrique, tout de même ?
Vous voulez mettre des conditions afin de savoir quel type d'instance retourner :
ça ressemble grandement à une portion de code pouvant être déclinée en fabrique !
Tu veux faire des fabriques de fabriques ? ?
Oui ! Notre fabrique actuelle nous permet de construire des objets accédant à des données se trouvant sur une base de données PostgreSQL. Mais la problématique maintenant est de pouvoir aussi utiliser des données provenant de fichiers XML...
Voici un petit schéma représentant la situation actuelle :
Et voilà ce à quoi on aspire :
Je pense que vous êtes tous d'accord pour dire que ces deux usines ont un processus de fabrication très similaire.
Par là, j'entends que nous allons utiliser les mêmes méthodes sur les objets sortant de ces deux usines.
Voyez ça un peu comme une grande marque de pain qui aurait beaucoup de boulangeries dans tous les pays du monde ! Cette firme a un savoir-faire évident, mais aussi des particularités : le pain ne se fait pas pareil dans tous les endroits du globe...
Pour vous, c'est comme si vous passiez commande directement au siège social qui, lui, va déléguer à l'usine qui permet de répondre à vos attentes !
Schématiquement, ça donne ceci :
Lorsque je vous dis ça, vous devez avoir une réaction quasi-immédiate :
héritage - polymorphisme !
Ce qui va changer le plus, par rapport à notre ancienne fabrique, c'est que nous n'utiliserons plus de méthodes statiques, mais des méthodes d'une instance concrète, et pour cause :
impossible de créer une classe abstraite ou une interface avec des méthodes statiques destinée à la redéfinition !
Donc, nous allons créer une classe abstraite pour nos futurs fabriques, celle-ci devra avoir les méthodes permettant de récupérer les différents DAO
ET une méthode permettant d'instancier la bonne fabrique !
Je vous ai préparé un diagramme de classe, vous verrez mieux comme ça :
Je vous ai même préparé les codes sources :
Secret (cliquez pour afficher)
Classe AbstractDAOFactory.java :
Code : Java 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45 | package com.sdz.dao;
public abstract class AbstractDAOFactory {
public static final int DAO_FACTORY = 0;
public static final int XML_DAO_FACTORY = 1;
/**
* Retourne un objet Classe interagissant avec la BDD
* @return
*/
public abstract DAO getClasseDAO();
/**
* Retourne un objet Professeur interagissant avec la BDD
* @return
*/
public abstract DAO getProfesseurDAO();
/**
* Retourne un objet Eleve interagissant avec la BDD
* @return
*/
public abstract DAO getEleveDAO();
/**
* Retourne un objet Matiere interagissant avec la BDD
* @return
*/
public abstract DAO getMatiereDAO();
/**
* Méthode permettant de récupérer les Factory
* @param type
* @return AbstractDAOFactory
*/
public static AbstractDAOFactory getFactory(int type){
switch(type){
case DAO_FACTORY:
return new DAOFactory();
case XML_DAO_FACTORY:
return new XMLDAOFactory();
default:
return null;
}
}
}
|
Classe DAOFactory.java
Code : Java 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30 | package com.sdz.dao;
import java.sql.Connection;
import com.sdz.connection.SdzConnection;
import com.sdz.dao.implement.ClasseDAO;
import com.sdz.dao.implement.EleveDAO;
import com.sdz.dao.implement.MatiereDAO;
import com.sdz.dao.implement.ProfesseurDAO;
public class DAOFactory extends AbstractDAOFactory{
protected static final Connection conn = SdzConnection.getInstance();
public DAO getClasseDAO(){
return new ClasseDAO(conn);
}
public DAO getProfesseurDAO(){
return new ProfesseurDAO(conn);
}
public DAO getEleveDAO(){
return new EleveDAO(conn);
}
public DAO getMatiereDAO(){
return new MatiereDAO(conn);
}
}
|
Classe XMLDAOFactory.java
Code : Java 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 | package com.sdz.dao;
public class XMLDAOFactory extends AbstractDAOFactory {
public DAO getClasseDAO() {
return null;
}
public DAO getEleveDAO() {
return null;
}
public DAO getMatiereDAO() {
return null;
}
public DAO getProfesseurDAO() {
return null;
}
}
|
Vous devez y voir plus clair ; même si la classe
XMLDAOFactory ne fait rien du tout, vous voyez le principe de base et c'est l'important !
Nous avons maintenant une hiérarchie de classes capables de travailler ensemble.
Je reprends le dernier exemple que nous avions réalisé, avec un peu de modifications...
Code : Java 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66 | import com.sdz.bean.Classe;
import com.sdz.bean.Eleve;
import com.sdz.bean.Matiere;
import com.sdz.bean.Professeur;
import com.sdz.dao.AbstractDAOFactory;
import com.sdz.dao.DAO;
import com.sdz.dao.DAOFactory;
public class TestDAO {
/**
* @param args
*/
public static void main(String[] args) {
System.out.println("");
//----------------------------------------------
//On va rechercher des élèves
//----------------------------------------------
AbstractDAOFactory adf = AbstractDAOFactory.getFactory(AbstractDAOFactory.DAO_FACTORY);
//On récupère un objet faisant le lien entre la base et nos objets
DAO<Eleve> eleveDao = adf.getEleveDAO();
for(int i = 1; i < 5; i++){
//On fait notre recherche
Eleve eleve = eleveDao.find(i);
System.out.println("\tELEVE N°" + eleve.getId() + " - NOM : " + eleve.getNom() + " - PRENOM : " + eleve.getPrenom());
}
System.out.println("\n\t************************************************");
//On fait de même pour une classe
DAO<Classe> classeDao = adf.getClasseDAO();
//On cherche la classe ayant pour ID 10
Classe classe = classeDao.find(10);
System.out.println("\tCLASSE DE " + classe.getNom());
//On récupère la liste des élèves
System.out.println("\n\tCelle-ci contient " + classe.getListEleve().size() + " élève(s)");
for(Eleve eleve : classe.getListEleve())
System.out.println("\t\t - " + eleve.getNom() + " " + eleve.getPrenom());
//Ainsi que la liste des professeurs
System.out.println("\n\tCelle-ci a " + classe.getListProfesseur().size() + " professeur(s)");
for(Professeur prof : classe.getListProfesseur()){
System.out.println("\t\t - Mr " + prof.getNom() + " " + prof.getPrenom() + " professeur de :");
//Tant qu'à faire, on prend aussi les matières... ^^
for(Matiere mat : prof.getListMatiere())
System.out.println("\t\t\t * " + mat.getNom());
}
System.out.println("\n\t************************************************");
//Un petit essai sur les matières
DAO<Matiere> matiereDao = adf.getMatiereDAO();
Matiere mat = matiereDao.find(2);
System.out.println("\tMATIERE " + mat.getId() + " : " + mat.getNom());
}
}
|
Et le résultat est le même qu'avant ! Tout fonctionne à merveille !
Ainsi, si vous voulez utiliser l'usine de fabrication XML, vous pouvez faire ceci :
AbstractDAOFactory adf = AbstractDAOFactory.getFactory(AbstractDAOFactory.XML_DAO_FACTORY);
.
Voilà, vous en savez plus sur ce pattern de conception et vous devriez être à même de coder le reste des méthodes (insertions, mise à jour et suppression), il n'y a rien de compliqué : ce sont juste des requêtes SQL...
Allez, et si nous allions faire un tour vers notre QCM ?