INF4067
2022-2023
Université de
Yaoundé I
INF4067 : UML et Design Patterns
Patterns de Construction
Octobre 2022
Valéry MONTHE
[email protected]
Bureau R114, Bloc pédagogique 1
Portée des Design Patterns
▪ Portée de Classe
o Focalisation sur les relations entre classes et leurs sous-classes
o Réutilisation par héritage
▪ Portée d’Instance (objet)
o Focalisation sur les relations entre les objets
o Réutilisation par composition
INF4067 || 2022-2023 Patterns de Construction 02/11/2022 2
Plan
1. Factory Methode
2. Abstract Factory
3. Singleton
4. Builder
5. Prototype
INF4067 || 2022-2023 Patterns de Construction 02/11/2022 3
Présentation
• Ils ont pour vocation d'abstraire les mécanismes de
création d'objets.
• Organiser la création d’objets
• Un système qui les utilise devient indépendant de la
façon dont les objets sont crées et, en particulier, des
mécanismes d'instanciation des classes concrètes.
• Ils encapsulent l'utilisation des classes concrètes et
favorisent ainsi l'utilisation des interfaces.
INF4067 || 2022-2023 Patterns de Construction 02/11/2022 4
Problème de la création d’objet
▪ Dans la plupart des langages à objets, la création d’objets se fait
grâce à l’opérateur new
▪ Dans certains cas, il est nécessaire de paramétrer la création
d’objets.
▪ Pourquoi l’utilisation de new est « mauvais »?
• Crée un couplage fort entre l’appelant et la classe instanciée
• Car une relation classe-à-classe est plus fragile
▪ Une relation classe-à-interface c’est l’idéal
• Crée un couplage faible
• Qu’est-ce que je dois faire?
• Que dois-je demander aux autres de faire?
o On ne se soucie pas de qui ils sont
INF4067 || 2022-2023 Patterns de Construction 02/11/2022 5
Problème de création : un exemple
▪ Exemple : On considère une méthode construitDoc qui crée des
documents PDF, RTF, ou HTML.
▪ Généralement, le type du document à créer sera transmis en
paramètre à la méthode
public Document conctruitDoc(String typeDoc)
{
Document resultat;
if (typeDoc.equals("PDF"))
resultat = new DocumentPDF();
else if (typeDoc.equals("RTF"))
resultat = new DocumentRTF();
else if (typeDoc.equals("HTML"))
resultat = new DocumentHTML();
//suite de la methode
}
INF4067 || 2022-2023 Patterns de Construction 02/11/2022 6
Problème de la création d’objet
• Il est difficile de paramétrer le mécanisme de création
d'objets,
o la classe transmise en paramètre à l’opérateur New ne pouvant être
substituée par une variable.
• L'utilisation de l'instruction conditionnelle présente un
inconvénient majeur :
o chaque changement dans la hiérarchie des classes à instancier
demande des modifications dans le code du client.
• Dans notre exemple, il faut changer le code de la méthode
construitDoc en cas d'ajout de nouvelles classes de
documents.
INF4067 || 2022-2023 Patterns de Construction 02/11/2022 7
Problème : un autre exemple
▪ Exemple : Soit une classe chien.
interface Aboyeur
{
void aboyer();
}
class Chien implements Aboyeur
{
// faire quelque chose de bien
}
class Test{
public static void main(String args[])
{
Aboyeur aboyeur = new Chien();
aboyeur.aboyer();
}
}
// De quoi nous soucions-nous ?
INF4067 || 2022-2023 Patterns de Construction 02/11/2022 8
Problème : un autre exemple
▪ Remplaçons l’opérateur new par un appel de méthode
interface Aboyeur
{
void aboyer();
private Aboyeur creerAboyeur()
{
return new Chien();
}
class Chien implements Aboyeur {
// faire quelque chose de bien
}
class Test{
public static void main(String args[]) {
Aboyeur aboyeur = creerAboyeur(); new Chien();
aboyeur.aboyer();
}
}
INF4067 || 2022-2023 Patterns de Construction 02/11/2022 9
Présentation
• 5 modèles principaux dans cette catégorie :
Nom Rôle
Créer un objet dont le type dépend du contexte.
Fabrique (Factory)
L’objet fait partie d’un ensemble de sous-classes
Fournir une interface unique pour instancier des
Fabrique abstraite
objets d'une même famille sans avoir à connaître
(abstract Factory)
les classes à instancier
Singleton (Singleton) Classe qui ne pourra avoir qu'une seule instance
Prototype
Création d'objet à partir d'un prototype
(Prototype)
Création d’objets complexes dont les différentes
Monteur (Builder)
parties doivent être créées suivant un ordre.
INF4067 || 2022-2023 Patterns de Construction 02/11/2022 10
Le patron Factory
INF4067 || 2022-2023 Patterns de Construction 02/11/2022 11
Factory (Fabrique)
▪ Permet de créer un objet dont le type dépend du contexte
▪ Cet objet fait partie d’un ensemble de sous classe
▪ L’objet retourné est toujours du type de la classe mère
▪ Le polymorphisme permet de spécialiser les traitements
▪ Il est utilisé lorsqu’à l’exécution il est nécessaire de déterminer
dynamiquement quel objet d’un ensemble de sous-classes doit être
instancier.
▪ Utilisable quand :
o Le client ne peut déterminer le type d’objet à créer qu'à l’exécution
o Il y a une volonté de centraliser la création d’objets
INF4067 || 2022-2023 Patterns de Construction 02/11/2022 12
Factory (Fabrique)
▪ L’utilisation d’une fabrique permet de rendre l’instanciation d’objets
plus flexible qu’avec l’opérateur new
▪ La fabrique peut s’implémenter de 2 manières :
• Déclarer une fabrique avec une méthode de création de l’objet qui
attend les données nécessaires pour déterminer le type de l’objet à
créer.
• Déclarer la fabrique abstraite et laisser ses sous classe créer les objets
INF4067 || 2022-2023 Patterns de Construction 02/11/2022 13
Factory Method
I. Utiliser une fabrique avec une méthode de création : Factory Method
1. Déclarer une fabrique avec une méthode de création de l’objet qui attend
les données nécessaires pour déterminer le type de l’objet à créer.
2. Structure générique : diagramme de classe du pattern
INF4067 || 2022-2023 Patterns de Construction 02/11/2022 14
Factory Method
I. Utiliser une fabrique avec une méthode de création : Factory Method
3. Participants
▪ Frabrique : la classe qui définit la méthode de création d’objets
▪ Produit : la classe abstraite dont les sous –classes seront instanciées
▪ ProduitConcret : les sous classes concrètes à instancier
▪ Client : le classe(programme) qui fait appel à la fabrique pour lui
fournir des objets de type Produit
INF4067 || 2022-2023 Patterns de Construction 02/11/2022 15
Factory Method : Exemple
Exemple : On gère deux types de produits dans un système. Mais le
programme qui se charge de manipuler ces produits ne connait le type de
produit à exécuter que lors de l’exécution. On souhaite utiliser le pattern
Factory Methode pour gérer cette situation.
INF4067 || 2022-2023 Patterns de Construction 02/11/2022 16
Factory Method : Exemple
Exemple : On gère deux types de produits dans un système. Mais le
programme qui se charge de manipuler ces produits ne connait le type de
produit à exécuter que lors de l’exécution. On souhaite utiliser le pattern
Factory Methode pour gérer cette situation.
INF4067 || 2022-2023 Patterns de Construction 02/11/2022 17
Factory Method : Exemple
La hiérarchie des produits
INF4067 || 2022-2023 Patterns de Construction 02/11/2022 18
Factory Method : Exemple
La classe qui contient la méthode fabrique
INF4067 || 2022-2023 Patterns de Construction 02/11/2022 19
Factory Method : Exemple
La classe utilisatrice de la fabrique : Client
INF4067 || 2022-2023 Patterns de Construction 02/11/2022 20
Factory
II. Déclarer la fabrique abstraite et laisser ses sous classe créer les objets
1. Structure générique : diagramme de classe du pattern
INF4067 || 2022-2023 Patterns de Construction 02/11/2022 21
Factory
Participants
▪ FrabriqueAbstraite : Classe abstraite qui abrite la signature de la méthode de
fabrique et l’implémentation des méthodes qui invoquent cette méthode de
fabrique.
▪ FabriqueConcrete : Classe concrète qui implémente la méthode fabrique. On
peut avoir plusieurs fabriques concrètes.
▪ Produit : la classe abstraite dont les sous –classes seront instanciées
▪ ProduitConcret : les sous classes concrètes à instancier
▪ Client : le classe(programme) qui fait appel à la fabrique pour lui fournir des
objets de type Produit
INF4067 || 2022-2023 Patterns de Construction 02/11/2022 22
Factory : Exemple
Exemple : On gère deux types de produits dans un système. Mais le
programme qui se charge de manipuler ces produits ne connait le type de
produit à exécuter que lors de l’exécution. On souhaite utiliser cette fois le
pattern Factory pour gérer cette situation.
INF4067 || 2022-2023 Patterns de Construction 02/11/2022 23
Factory Method : Exemple
La hiérarchie des produits
INF4067 || 2022-2023 Patterns de Construction 02/11/2022 24
Factory : Exemple
La hiérarchie de la fabrique
INF4067 || 2022-2023 Patterns de Construction 02/11/2022 25
Factory Method : Exemple
La classe utilisatrice de la fabrique : Client
INF4067 || 2022-2023 Patterns de Construction 02/11/2022 26
Le patron Abstract Factory
INF4067 || 2022-2023 Patterns de Construction 02/11/2022 27
Abstract Factory (Fabrique abstraite)
▪ Le but est de créer des objets regroupés en familles sans avoir à
connaître leurs classes concrètes.
▪ Permet de fournir une interface unique pour instancier des objets
d’une même famille sans avoir à connaitre les classes à instancier.
▪ Son utilisation est pertinente lorsque :
o Le système est indépendant de la création des objets qu’il utilise
o Le système est capable de créer des objets d’une même famille
INF4067 || 2022-2023 Patterns de Construction 02/11/2022 28
Abstract Factory : Structure générique
Une fabrique abstraite et une fabrique concrète pour chaque famille d’objets.
INF4067 || 2022-2023 Patterns de Construction 02/11/2022 29
Abstract Factory : les participants
▪ FrabriqueAbstraite : interface spécifiant les signatures des méthodes
créant les différents objets
▪ FrabriqueConcrete (1 et 2) : classes implémentant les méthodes de
création d’objets. Connaissent les familles et les produits, capable de
créer une instance d’un produit pour une famille.
▪ Produit (A et B) : interfaces (ou classes abstraites) des produits
indépendamment de leur famille.
▪ Produit (Ax et Bx) : introduisent les familles de produits
▪ Client : le classe(programme) qui fait appel à la fabrique pour lui
fournir des objets de type Produit
INF4067 || 2022-2023 Patterns de Construction 02/11/2022 30
Abstract Factory : les participants
▪ C’est une des classes filles de la fabrique qui se charge de la
création des objets d’une famille
▪ Le client utilise une implémentation concrète de la fabrique pour
avoir les produits
▪ Il n’y a pas de relation entre client et classe concrète des produit
▪ Celle-ci peut renvoyer n’importe quelle classe qui hérite de la
classe abstraite.
▪ Ceci permet :
• De remplacer une classe concrète par une autre
• D’ajouter de nouveau types d’objets qui héritent de la classe abstraite sans
modifier le code utilisé par la fabrique.
INF4067 || 2022-2023 Patterns de Construction 02/11/2022 31
Abstract Factory : Exemple
Exemple : On gère deux types de produits. Dans chaque type, les produits
sont regroupés par catégorie. Mais le programme qui se charge de manipuler
ces produits ne connait que les types de produits, et c’est à l’exécution que la
catégorie du produit est déterminée. On souhaite utiliser le pattern Abstract
Factory pour gérer cette situation.
INF4067 || 2022-2023 Patterns de Construction 02/11/2022 32
Abstract Factory : Exemple
INF4067 || 2022-2023 Patterns de Construction 02/11/2022 33
Abstract Factory : Exemple, les produits
1. package construction.abstractFactory;
2. public abstract class ProduitA {
3. public abstract void methodeA();
4. }
5. public class ProduitA1 extends ProduitA {
6. public void methodeA() {
7. System.out.println("ProduitA1.methodeA()");
8. }
9. }
10. public class ProduitA2 extends ProduitA {
11. public void methodeA() {
12. System.out.println("ProduitA2.methodeA()");
13. }
14. }
INF4067 || 2022-2023 Patterns de Construction 02/11/2022 34
Abstract Factory : Exemple, la fabrique
1. package construction.abstractFactory;
2. public interface IProduitFactory {
3. public ProduitA getProduitA();
4. public ProduitB getProduitB();
5. }
6. public class ProduitFactory1 implements IProduitFactory {
7. public ProduitA getProduitA() {
8. return new ProduitA1();
9. }
10. public ProduitB getProduitB() {
11. return new ProduitB1();
12. }
13. }
14. public class ProduitFactory2 implements IProduitFactory {
15. public ProduitA getProduitA() {
16. return new ProduitA2();
17. }
18. public ProduitB getProduitB() {
19. return new ProduitB2();
20. }
21. }
INF4067 || 2022-2023 Patterns de Construction 02/11/2022 35
Abstract Factory : Exemple, le client
1. package construction.abstractFactory;
2. public class Client {
3. public static void main(String[] args) {
4. IProduitFactory produitFactory1 = new ProduitFactory1();
5. IProduitFactory produitFactory2 = new ProduitFactory2();
6. ProduitA produitA = null;
7. ProduitB produitB = null;
8. System.out.println("Utilisation de la premiere fabrique");
9. produitA = produitFactory1.getProduitA();
10. produitB = produitFactory1.getProduitB();
11. produitA.methodeA();
12. produitB.methodeB();
13. System.out.println("Utilisation de la seconde fabrique");
14. produitA = produitFactory2.getProduitA();
15. produitB = produitFactory2.getProduitB();
16. produitA.methodeA();
17. produitB.methodeB();
18. }
19. }
INF4067 || 2022-2023 Patterns de Construction 02/11/2022 36
Le patron Singleton
INF4067 || 2022-2023 Patterns de Construction 02/11/2022 37
Singleton
• L’objectif du pattern SINGLETON est de garantir qu’une classe ne
possède qu’une seule instance et de fournir un point d’accès global à
celle-ci.
• Fourni une méthode de classe unique retournant cette unique instance.
• Restreint l'instanciation d'une classe à un seul point.
• Est utilisé lorsque l'on a besoin d'exactement un objet pour coordonner
des opérations dans un système.
• L’instance ne doit être accessible qu’au travers d’une méthode de
classe.
• On l’implémente en écrivant une classe contenant une méthode qui
crée une instance uniquement s'il n'en existe pas encore. Sinon elle
renvoie une référence vers l'objet qui existe déjà.
• Il faudra veiller à ce que le constructeur de la classe soit privé, afin de
s'assurer que la classe ne puisse être instanciée autrement que par la
méthode de création contrôlée.
INF4067 || 2022-2023 Patterns de Construction 02/11/2022 38
Singleton : Mise en ouvre
• On l’implémente en écrivant une classe contenant :
– une méthode qui crée une instance uniquement s'il n'en existe pas
encore.
– Sinon elle renvoie une référence vers l'objet qui existe déjà.
• Il faudra veiller à ce que le constructeur de la classe soit privé, afin de
s'assurer que la classe ne puisse être instanciée autrement que par la
méthode de création contrôlée.
INF4067 || 2022-2023 Patterns de Construction 02/11/2022 39
Singleton : Structure
Singleton
-instance : Singleton
-Singleton ()
+getInstance () : Singleton
INF4067 || 2022-2023 Patterns de Construction 02/11/2022 40
Singleton : les participants
▪ Un seul participant : la classe singleton
▪ Ses propriétés :
• Le ou les constructeurs sont privés. Redéfinir le constructeur par
défaut, si aucun n’est explicitement défini.
• Une attribut de classe : pour stocker l’unique instance en cours
• Un getter static et public : pour renvoyer l’instance et la créer au
besoin
INF4067 || 2022-2023 Patterns de Construction 02/11/2022 41
Singleton : Exemple
public final class Singleton
{
private static Singleton instance = null;
// D'autres attributs, classiques et non "static".
private String attrib1;
private int attrib2;
// Constructeur de l'objet.
private Singleton()
{
// La présence d'un constructeur privé supprime le constructeur
public par défaut.
super();
}
.
..
INF4067 || 2022-2023 Patterns de Construction 02/11/2022 42
Singleton : Exemple
// Méthode renvoyant une instance de la classe Singleton
Public static Singleton getInstance()
{
if (instance == null)
{
instance = new Singleton();
}
return instance;
}
// D'autres méthodes classiques et non "static".
public void op1(int x, int y, int z)
{
...
this. attrib1 = "bonjour";
}
public void op2(int x, int y, int z)
{
...
}
}
INF4067 || 2022-2023 Patterns de Construction 02/11/2022 43
Singleton : Exemple
//------------------utilisation possible--------------------------------------
public static void main(String[] args)
{ Singleton.getInstance().op1(1,2,3);
Singleton.getInstance().op2(3,4,5);
}
// ou comme ceci------------
public static void main(String[] args)
{ Singleton singl = Singleton.getInstance();
singl.op1(1,2,3);
singl.op2(3,4,5);
}
INF4067 || 2022-2023 Patterns de Construction 02/11/2022 44
Singleton : Exemple
1. package construction.singleton;
2. public final class Singleton {
3. private static Singleton instance = null;
4.
5. // D'autres attributs, classiques et non "static".
6. private int x;
7. private int y;
8. // Constructeur de l'objet.
9. private Singleton()
10. {
11. // La présence d'un constructeur privé supprime le constructeur public par défaut.
12. super();
13. }
14.
15. // un autre constructeur.
16. private Singleton(int x, int y)
17. {
18. this.x=x;
19. this.y=y;
20.
21. }
22. // ………… suite de la classe, diapo suivante
INF4067 || 2022-2023 Patterns de Construction 02/11/2022 45
Singleton : Exemple
1. // Méthode renvoyant une instance de la 1. // D'autres méthodes classiques et non "static".
classe Singleton 2. public int somme(int x, int y)
2. public static Singleton getInstance() 3. {
3. { 4.
4. if (instance == null) 5. return x+y;
5. { 6. }
6. instance = new 7.
Singleton(); 8. public float moyenne(int x, int y)
7. } 9. {
8. return instance; 10. return somme(x, y)/2;
9. } 11. }
10. 12.
11. // Méthode renvoyant une instance de 13. public void affiche()
la classe Singleton 14. {
12. public static Singleton 15. System.out.println("\nJe suis une instance mes
getInstance(int x, int y) valeurs sont : x = " + this.x + " et y = " +
13. { this.y);
14. if (instance == null) 16. }
15. {
16. instance = new 17.// redefinir la méthode clone pour empêcher son
Singleton(x, y); utilisation
17. } 18. @Override
18. return instance; 19. public Object clone() throws
19. } CloneNotSupportedException {
20. 20. throw new CloneNotSupportedException();
21. }
22.}
23.// fin de la classe Singleton
INF4067 || 2022-2023 Patterns de Construction 02/11/2022 46
Singleton : Exemple
1. // Une classe de test
2. package construction.singleton;
3. public class TestSingleton {
4. public static void main(String[] args)
5. {
6. int som = Singleton.getInstance().somme(2, 5);
7. System.out.printf("la somme est %d",som);
8. Singleton s1 = Singleton.getInstance(8, 3);
9. s1.affiche();
10. Singleton s2 = Singleton.getInstance(5, 9);
11. s2.affiche();
12. }
13. }
14.
INF4067 || 2022-2023 Patterns de Construction 02/11/2022 47
Le patron Builder
INF4067 || 2022-2023 Patterns de Construction 02/11/2022 48
Builder (Monteur)
• Créer des objets complexes à partir d’autres objets sources.
• Ces parties (objets sources) doivent (généralement) être créées
suivant un ordre ou un algorithme spécifique.
• Concrètement, assembler plusieurs objets pour les « monter » et
n’en faire qu’un.
• Son but est donc d’encapsuler la construction d’objets complexes de
sorte qu’un client puisse créer ces objets sans se préoccuper des
différents étapes nécessaires.
• Chaque objet source peut servir à construire une partie de l’objet
complexe( objet cible)
INF4067 || 2022-2023 Patterns de Construction 02/11/2022 49
Builder : Structure
INF4067 || 2022-2023 Patterns de Construction 02/11/2022 50
Builder : les participants
▪ MonteurAbstrait : précise une classe abstraite (ou une interface)
pour la création de partie d’un objet Produit
▪ MonteurConcret : construit et assemble des parties du produit
par implémentation des méthodes du MonteurAbstrait
▪ Directeur : construit un objet en utilisant l’interface du Monteur
▪ Produit : représente l’objet complexe en cours de construction
INF4067 || 2022-2023 Patterns de Construction 02/11/2022 51
Builder : Collaboration
INF4067 || 2022-2023 Patterns de Construction 02/11/2022 52
Builder : Collaboration
▪ Le client crée l’objet Directeur en lui passant une instance du
MonteurConcret
▪ Le Directeur utilise le Monteur chaque fois qu’une partie du
produit doit être construite.
▪ Le Monteur gère les requêtes du Directeur et le Produit en parties
▪ Le client récupère le Produit auprès du Monteur
INF4067 || 2022-2023 Patterns de Construction 02/11/2022 53
Builder : Exemple
On souhaite fabriquer des pizza. On a 2 types de pizza : la pizza
reine et le pizza piquante,
Pour fabriquer une pizza : on prépare la pate, on prépare et ajoute
une sauce et on prépare et ajoute une garniture.
– pour la pizza reine, on utilise : pate = « croisée », sauce =
« douce » et garniture = « jambon et champignon »
– pour la pizza piquante, on utilise : pate = « feuilletée », sauce =
« piquante » et garniture = « pepperoni + salami »
On veut utiliser le design pattern Builder pour faciliter la fabrication
des pizza.
1. Proposer une modélisation sous forme de diagramme de classe
2. Proposer le code source correspondant.
INF4067 || 2022-2023 Patterns de Construction 02/11/2022 54
Builder : Exemple
INF4067 || 2022-2023 Patterns de Construction 02/11/2022 55
Builder : Exemple
/* Produit */
class Pizza {
private String pate = "";
private String sauce = "";
private String garniture = "";
public void setPate(String pate) { this.pate = pate; }
public void setSauce(String sauce) { this.sauce = sauce; }
public void setGarniture(String garniture) { this.garniture =
garniture; }
public void print() {
System.out.println(this.toString());
System.out.println("Pate = " + pate + "\nSauce = " + sauce +
"\nGarniture = " + garniture);}
}
INF4067 || 2022-2023 Patterns de Construction 02/11/2022 56
Builder : Exemple
/* Monteur */
abstract class MonteurPizza {
protected Pizza pizza;
public Pizza getPizza() { return pizza; }
public void creerNouvellePizza() { pizza = new Pizza(); }
public abstract void monterPate();
public abstract void monterSauce();
public abstract void monterGarniture();
}
/* MonteurConcret */
class MonteurPizzaReine extends MonteurPizza {
public void monterPate() { pizza.setPate("croisée"); }
public void monterSauce() { pizza.setSauce("douce"); }
public void monterGarniture() {
pizza.setGarniture("jambon+champignon"); }
}
/* MonteurConcret */
class MonteurPizzaPiquante extends MonteurPizza {
public void monterPate() { pizza.setPate("feuilletée"); }
public void monterSauce() { pizza.setSauce("piquante"); }
public void monterGarniture() { pizza.setGarniture("pepperoni+salami");
}
}
INF4067 || 2022-2023 Patterns de Construction 02/11/2022 57
Bibliographie et ressources
Ouvrages recommandés
• Software Architecture in Practice, 3e édition, Len Bass, Paul Clements
et Rick Kazman, Addison-Wesley, 2012.
• “Design Patterns - Elements of Reusable Object-Oriented Software”,
Erich Gamma, Richard Helm, Ralph Johnson, John Vlissides
• POSA 1 - “Pattern-Oriented Software Architecture – A System of
Patterns”, Vol. 1, Frank Buschmann, Regine Meunier, Hans Rohnert,
Peter Sommerland, Michael Stal
INF4067 || 2022-2023 Patterns de Construction 02/11/2022 58