Programmation Objet en Java Cours 9 Design Patterns 1 (C) 2005, Frédéric Peschanski 1 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: Frederic.Peschanski@lip6.fr
Programmation Objet en Java Cours 9 Design Patterns 1 (C) 2005, Frédéric Peschanski 2 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»
Programmation Objet en Java Cours 9 Design Patterns 1 (C) 2005, Frédéric Peschanski 3 De la Bidouille OO à la ProgrammationOO Principes objets Encapsulation Héritage, classes abstraites Polymorphisme Particularité de Java Interfaces Question 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
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 5 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);
Programmation Objet en Java Cours 9 Design Patterns 1 (C) 2005, Frédéric Peschanski 6 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
Programmation Objet en Java Cours 9 Design Patterns 1 (C) 2005, Frédéric Peschanski 7 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
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 9 Exemple : le pattern Bridge (3/5) Structure Constituants
Programmation Objet en Java Cours 9 Design Patterns 1 (C) 2005, Frédéric Peschanski 10 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;
Programmation Objet en Java Cours 9 Design Patterns 1 (C) 2005, Frédéric Peschanski 11 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;
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 13 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.)
Principe 1 Programmation Objet en Java Cours 9 Design Patterns 1 (C) 2005, Frédéric Peschanski 14 Principes communs aux patterns 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»
Programmation Objet en Java Cours 9 Design Patterns 1 (C) 2005, Frédéric Peschanski 15 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
Programmation Objet en Java Cours 9 Design Patterns 1 (C) 2005, Frédéric Peschanski 16 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
Programmation Objet en Java Cours 9 Design Patterns 1 (C) 2005, Frédéric Peschanski 17 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!
Programmation Objet en Java Cours 9 Design Patterns 1 (C) 2005, Frédéric Peschanski 18 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
Programmation Objet en Java Cours 9 Design Patterns 1 (C) 2005, Frédéric Peschanski 19 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é
Programmation Objet en Java Cours 9 Design Patterns 1 (C) 2005, Frédéric Peschanski 20 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
Programmation Objet en Java Cours 9 Design Patterns 1 (C) 2005, Frédéric Peschanski 21 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.
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 23 Le Design Pattern FactoryMethod (2/4) Structure
Programmation Objet en Java Cours 9 Design Patterns 1 (C) 2005, Frédéric Peschanski 24 Implémentation cf. TD Le Design Pattern FactoryMethod (3/4) 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();
Programmation Objet en Java Cours 9 Design Patterns 1 (C) 2005, Frédéric Peschanski 25 Implémentation cf. TD Le Design Pattern FactoryMethod (4/4) 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);
Programmation Objet en Java Cours 9 Design Patterns 1 (C) 2005, Frédéric Peschanski 26 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.
Programmation Objet en Java Cours 9 Design Patterns 1 (C) 2005, Frédéric Peschanski 27 Pattern structurel : Adapter (2/2) Structure
Programmation Objet en Java Cours 9 Design Patterns 1 (C) 2005, Frédéric Peschanski 28 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