Cours Java : deuxième saison

publicité
Programmation Objet en Java – Cours 9 Design Patterns 1 – (C) 2005, Frédéric Peschanski
Cours Java : deuxième saison
➢
Cours 7 : Exceptions, tests unitaires et assertions
➢
Cours 8 : Design Patterns 1
➢
Cours 9 : Design Patterns 2
➢
Cours 10 : Interfaces graphiques en Swing
➢
Cours 11 : Collections
Contact: [email protected]
1
Programmation Objet en Java – Cours 9 Design Patterns 1 – (C) 2005, Frédéric Peschanski
Les Design Patterns
Première partie
●
Introduction aux Design Patterns
●
Exemple : le Pattern « Bridge »
–
●
●
Héritage vs. délégation
Patterns créateurs
–
Les idiomes « SimpleFactory »
–
Le pattern « FactoryMethod »
–
Les variantes « AbstractFactory » et « Builder »
–
Le pattern « Singleton »
Patterns structuraux
–
« Adapter » et « Façade »
2
Programmation Objet en Java – Cours 9 Design Patterns 1 – (C) 2005, Frédéric Peschanski
De la B OO à la P
idouille
●
●
–
Encapsulation
–
Héritage, classes abstraites
–
Polymorphisme
Particularité de Java
Interfaces
Question
–
●
OO
Principes objets
–
●
rogrammation
Comment combiner ces différents outils pour écrire des programmes ou boîtes­à­outils flexibles, réutilisables, efficaces, etc, etc.
Important : c'est une question difficile
3
Programmation Objet en Java – Cours 9 Design Patterns 1 – (C) 2005, Frédéric Peschanski
4
Les Design Patterns
●
Définition
–
●
●
Elément de conception réutilisable permettant de résoudre un problème récurrent en programmation orientée objet.
Historique
–
Inspirées d'une méthode de conception d'immeuble en architecture [Alexander, 77]
–
Introduites par le «GOF» dans le livre Design Patterns en 99 (dans le «GOF» 23 patterns «standards»)
Pourquoi les patterns ?
–
Des « recettes d'expert » ayant fait leurs preuves
–
Un vocabulaire commun pour les architectes logiciels
–
Incontournable dans le monde de la P.O.O
Programmation Objet en Java – Cours 9 Design Patterns 1 – (C) 2005, Frédéric Peschanski
Les idiômes de programmation
Un «bout de programme Java» que l'on tape systématiquement lorsque l'on veut résoudre un problème «récurrent»
➔
Exemple 1 : parcourir les éléments d'un tableau
for(int i=0;i<tableau.length;i++) {
tableau[i] = ... patati patata ...
}
Exemple 2 : utiliser une fonctionnalité du JDK
try {
// fonctionnalité XYZ du jdk
XYZ(...);
} catch(XYZException e) {
e.printStackTrace(System.err);
}
5
Programmation Objet en Java – Cours 9 Design Patterns 1 – (C) 2005, Frédéric Peschanski
Conception vs. Programmation
●
Les designs patterns sont des éléments de conception
–
Pas au niveau du langage de programmation (donc pas spécifique à Java, les patterns «marchent» aussi en C++, en Python, en Eiffel, etc.)
–
●
Au niveau du modèle objet uniquement ( essentiellement classes, interfaces, méthodes)
Un pattern ne s'invente pas, il se découvre
–
Dans des programmes de grande taille et utilisés dans l'industrie
–
Dans différents langages de programmation objet
6
Programmation Objet en Java – Cours 9 Design Patterns 1 – (C) 2005, Frédéric Peschanski
Exemple : le pattern Bridge (1/5)
Intention : Découple les abstractions des implémentations pour pouvoir
gérer les deux de façon la plus indépendante possible
Motivations
Approche classique : abstraction = classe mère abstraite,
implémentation = sous­classe concrète
Problème : on veut faire évoluer les abstractions indépendemment
des implémentations
Exemple : Abstraction Widget, Implémentations Bouton, Menu, etc.
On voudrait d'un côté: Et de l'autre côté:
WinWidget : widget pour windows
WinBouton, X11Bouton, etc. X11Widget : widget pour Unix
X11Menu, MacMenu, etc.
MacWidget : widget pour MacOS
7
Programmation Objet en Java – Cours 9 Design Patterns 1 – (C) 2005, Frédéric Peschanski
8
Exemple : le pattern Bridge (2/5)
Indications d'utilisation
●
●
●
●
●
●
On veut éviter un lien définitif entre une abstraction et son implémentation
On veut raffiner les abstractions d'un côté et les implémentations de l'autre
Les abstractions ne sont pas des interfaces, on veut leur attacher du code
Le code du client dépend des abstractions, on peut donc faire varier les implémentations
On veut éviter une prolifération de classes et se préserver contre un diagramme d'héritage complexe
etc.
Programmation Objet en Java – Cours 9 Design Patterns 1 – (C) 2005, Frédéric Peschanski
Exemple : le pattern Bridge (3/5)
Structure
Constituants
9
Programmation Objet en Java – Cours 9 Design Patterns 1 – (C) 2005, Frédéric Peschanski
Exemple : le pattern Bridge (4/5)
Implémentation Héritage vs. Délégation
// Abstraction
public abstract class Propriete {
private double loyer;
protected Propriete(double loyer) {
this.loyer = loyer;
}
public double getLoyer() { return loyer; }
public abstract double cout();
}
// Implémentation
public class Gare extends Propriete {
private int nb_gares;
public Gare() {
super(2500); nb_gares = 1;
}
public void addGare() { nb_gares++; }
public double cout() { return getLoyer()*nb_gares; }
}
10
Programmation Objet en Java – Cours 9 Design Patterns 1 – (C) 2005, Frédéric Peschanski
Exemple : le pattern Bridge (5/5)
Implémentation Héritage vs. Délégation
// Abstraction dans le pattern Bridge
public abstract class Propriete {
private double loyer;
private ProprieteImpl impl;
protected Propriete(ProprieteImpl impl, double loyer) {
this.loyer = loyer; this.impl = impl;
}
public double getLoyer() { return loyer; }
public double cout() { impl.cout(loyer); }
}
// Implémentation générique
public abstract class ProprieteImpl {
public abstract double cout(double loyer);
}
// Implémentation concrète
public class Gare extends ProprieteImpl {
// à par la méthode cout(), comme slide précédent
public double cout(double loyer) {
return loyer*nb_gares;
}
}
11
Programmation Objet en Java – Cours 9 Design Patterns 1 – (C) 2005, Frédéric Peschanski
12
Description d'un pattern
●
●
●
●
●
●
●
●
●
●
●
Nom et classification (ex. bridge/structurel)
Intention : description générale et succinte
Alias : autres noms connus pour le pattern (pont,poignée/corps)
Motivation : au moins 2 exemples/scénarios qui montrent pourquoi on a besoin du pattern
Indications d'utilisation : une liste des situations qui justifient de l'utilisation du pattern
Structure : un diagramme de classe UML indépendant du langage de programmation
Constituants : Explication des différentes classes qui interviennent dans la structure du pattern
Implémentation : les principes, pièges, astuces, techniques pour implanter le pattern dans un langage objet donné (pour nous, Java).
Utilisations remarquables : des programmes réels dans lesquels on trouve le pattern Limites : les limites concernant l'utilisation du pattern
etc.
Programmation Objet en Java – Cours 9 Design Patterns 1 – (C) 2005, Frédéric Peschanski
Classification des patterns
●
●
●
Patterns Créateurs
–
S'intéressent à la construction des objets (pour «aider» le new, clone, etc.)
–
Patterns FactoryMethod, AbstractFactory, Builder, Singleton
Patterns Structuraux
–
travaillent essentiellement sur des aspects statiques, à «l'extérieur» des classes
–
Bridge, Adapter et Composite (etc.)
Patterns Comportementaux
–
travaillent essentiellement sur des aspects dynamiques, à «l'intérieur» des classes et parfois au niveaux des instances
–
Strategy, Decorator, Observer, Visitor (etc.)
13
Programmation Objet en Java – Cours 9 Design Patterns 1 – (C) 2005, Frédéric Peschanski
Principes communs aux patterns
●
Principe 1
–
Favoriser la composition (lien dynamique, flexible) sur l'héritage (lien statique, peu flexible)
●
●
●
La délégation est un exemple d'outil pour la composition
Attention: favoriser ne veut pas dire remplacer systématiquement, l'héritage est largement utilisé aussi !
Principe 2
–
Les clients programment en priorité pour des interfaces (ou abstractions, classes abstraites, etc) plutôt qu'en lien direct avec les implémentations (classes concrètes)
–
ex. le pattern «bridge»
14
Programmation Objet en Java – Cours 9 Design Patterns 1 – (C) 2005, Frédéric Peschanski
Patterns créateurs
●
●
Les idiômes et patterns Factory
–
Simple FactoryMethod : une méthode statique qui crée un objet
–
FactoryMethod : un pattern qui généralise le précédent
–
Simple Factory : une classe qui se charge de créer des objets
–
AbstractFactory : un pattern qui introduit une interface pour générer des objets appartenant à la même «famille» (généralisation des trois précédents)
Le pattern Builder (cf. TME)
–
●
Une variante de l'AbstractFactory pour «monter» un objet par parties et/ou en plusieurs étapes
Le pattern Singleton (cf. TD+TME)
–
Un objet (instance) dont on est sûr qu'il est globalement unique
15
Programmation Objet en Java – Cours 9 Design Patterns 1 – (C) 2005, Frédéric Peschanski
Les patterns Factory
●
●
●
Le problème du new
–
Le new est l'outil de base pour créer des instances à partir de classe mais on l'appelle directement sur une classe concrète
–
Cela «casse» donc la règle qui veut que notre code client ne doit pas dépendre (trop) des classes concrètes
L'idiôme de programmation SimpleFactory
–
Idée : introduire une classe complète qui permet de créer des instances d'autres classes
–
Problème : on programme toujours pour des implémentations, pas pour des interfaces
Le design pattern AbstractFactory
–
Idée : Introduire une interface de création d'objets ou de familles d'objets
–
On peut alors introduire des variantes dans les classes de création
16
Programmation Objet en Java – Cours 9 Design Patterns 1 – (C) 2005, Frédéric Peschanski
Exemple : Les Zanimos (1/3)
public class BebePhoque extends Phoque {
...
public BebePhoque(String nom) {
super(nom,0); // il a 0 an
// ici initialiser les attributs d'un bébé animal
}
...
}
...
BebePhoque george = new BebePhoque("george");
// bizarre quand même, un bébé phoque qui se crée
// lui-même !
17
Programmation Objet en Java – Cours 9 Design Patterns 1 – (C) 2005, Frédéric Peschanski
Patterns créateurs
●
●
●
Le problème du new
–
Le new est l'outil de base pour créer des instances à partir de classe mais on l'appelle directement sur une classe concrète
–
Cela «casse» donc la règle qui veut que notre code client ne doit pas dépendre (trop) des classes concrètes
L'idiôme de programmation SimpleFactory
–
Idée : introduire une classe complète qui permet de créer des instances d'autres classes
–
Problème : on programme toujours pour des implémentations, pas pour des interfaces
Le design pattern AbstractFactory
–
Idée : Introduire une interface de création d'objets ou de familles d'objets
–
On peut alors introduire des variantes dans les classes de création
18
Programmation Objet en Java – Cours 9 Design Patterns 1 – (C) 2005, Frédéric Peschanski
Exemple : Les Zanimos (2/3)
public class BebePhoque extends Phoque {
...
}
// Voilà la classe qui sert de SimpleFactory
public class MamanPhoque {
...
public BebePhoque mettreBas(String nom) {
return new BebePhoque(nom);
}
}
...
MamanPhoque maman = ... ; // on a une maman phoque
BebePhoque george = maman.mettreBas("george");
// c'est mieux, c'est la maman qui fait le bébé
19
Programmation Objet en Java – Cours 9 Design Patterns 1 – (C) 2005, Frédéric Peschanski
Patterns créateurs
●
●
●
Le problème du new
–
Le new est l'outil de base pour créer des instances à partir de classe mais on l'appelle directement sur une classe concrète
–
Cela «casse» donc la règle qui veut que notre code client ne doit pas dépendre (trop) des classes concrètes
L'idiôme de programmation SimpleFactory
–
Idée : introduire une classe complète qui permet de créer des instances d'autres classes
–
Problème : on programme toujours pour des implémentations, pas pour des interfaces
Le design pattern AbstractFactory
–
Idée : Introduire une interface de création d'objets ou de familles d'objets
–
On peut alors introduire des variantes dans les classes de création
20
Programmation Objet en Java – Cours 9 Design Patterns 1 – (C) 2005, Frédéric Peschanski
Exemple : Les Zanimos (3/3)
// Voilà l'interface qui sert d'AbstractFactory
public interface Clinique {
public BebePhoque mettreBasPhoque(String nom);
public BebeGirafe mettreBasGirafe(int cm, String nom);
public Animal mettreBas(String typeAnimal, String nom);
public Animal[] creerStock(String type, String[] noms);
}
// Et une implémentation
public class CliniqueDuPoleNord implements Clinique {
...
public BebePhoque mettreBas(String nom) {
return new BebePhoque(nom);
}
}
...
PoleNordClinique veto = ... ; // on a une maman phoque
BebePhoque george = veto.mettreBas("george");
// là c'est plus flexible, puisqu'on peut imaginer
// cliniques pour d'autres types d'animaux, etc.
21
Programmation Objet en Java – Cours 9 Design Patterns 1 – (C) 2005, Frédéric Peschanski
22
Le Design Pattern FactoryMethod (1/4)
Intention : Définit une interface de méthode pour la création d'objets . La construction de l'objet est prise en charge par des implémentations de l'interface de création
Motivations cf. petit exemple au tableau + TD
Indications d'utilisation
●
●
Une classe ne peut prévoir à l'avance la classe des objets qu'elle aura à créer (par exemple, on introduit de nouveaux types de documents)
On utilisera la Factory Method également lorsque la classe tierce de création peut faire autre chose que juste s'occuper de la création (ex. la classe Application gère d'autres aspects que la création de documents).
Programmation Objet en Java – Cours 9 Design Patterns 1 – (C) 2005, Frédéric Peschanski
Structure
Le Design Pattern FactoryMethod (2/4)
23
Programmation Objet en Java – Cours 9 Design Patterns 1 – (C) 2005, Frédéric Peschanski
Le Design Pattern FactoryMethod (3/4)
Implémentation
cf. TD
Variante SimpleFactoryMethod et utilité pour enlever les casts inutiles
Par exemple dans le cas du clone:
public class Cellule {
...
public Object clone(Cellule souche) {
// ici code du clonage
}
}
// code d'un client avec cast
Cellule monClone = (Cellule) souche1.clone();
24
Programmation Objet en Java – Cours 9 Design Patterns 1 – (C) 2005, Frédéric Peschanski
Le Design Pattern FactoryMethod (4/4)
Implémentation
cf. TD
Variante SimpleFactoryMethod et utilité pour enlever les casts inutiles
Par exemple dans le cas du clone:
public class Cellule {
...
public Object clone(Cellule souche) {
// ici code du clonage
}
// c'est une SimpleFactoryMethod
public static Cellule clonerCellule(Cellule souche) {
return (Cellule) souche.clone();
}
}
// code d'un client sans cast
Cellule monClone = Cellule.clonerCellule(souche1);
25
Programmation Objet en Java – Cours 9 Design Patterns 1 – (C) 2005, Frédéric Peschanski
Pattern structurel : Adapter (1/2)
Intention : Convertir l'interface d'une classe en une autre conforme à l'attente du client. L'adaptateur permet à de classes de collaborer, qui n'aurait pu le faire du fait des interfaces incompatibles.
Motivations
Problème très général : on a un objet d'une classe Client qui veut utiliser
un objet de classe B mais le client ne sait manipuler des objets de classe A.
Il faut donc adapter la classe B à l'interface de A pour que le Client puisse
finalement utiliser B.
Exemple concret : On a une classe Appareil110v qui veut utiliser une classe Courant220v mais l'interface de l'Appareil110v demande d'utiliser une classe Courant220v. L'idée est de créer une classe Adaptateur110v220v qui résolve le problème. 26
Programmation Objet en Java – Cours 9 Design Patterns 1 – (C) 2005, Frédéric Peschanski
Pattern structurel : Adapter (2/2)
Structure
27
Programmation Objet en Java – Cours 9 Design Patterns 1 – (C) 2005, Frédéric Peschanski
Conclusion
●
A partir de maintenant, vous savez:
–
ce qu'est un idiome de programmation
–
ce qu'est la délégation
–
les principes des design patterns
–
les détails des patterns Bridge, AbstractFactory (et variante simplifiée SimpleFactory), FactoryMethod (et variante simplifiée SimpleFactoryMethod) et Adapter
=> A partir de maintenant, vous pouvez apprendre à implémenter des patterns et comprendre à quel moment on en a besoin
28
Téléchargement