Programmation Objet en Java – Cours 9 Design Patterns 1 ...samirb5.free.fr/cours/JAVA/java -...

28
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 [email protected]

Transcript of Programmation Objet en Java – Cours 9 Design Patterns 1 ...samirb5.free.fr/cours/JAVA/java -...

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:  [email protected]

Programmation Objet en Java – Cours 9 Design Patterns 1 – (C) 2005, Frédéric Peschanski 2

Les Design PatternsPremiè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 JDKtry { // 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 pouvoirgérer les deux de façon la plus indépendante possibleMotivationsApproche 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é: 

WinWidget : widget pour windowsX11Widget : widget pour UnixMacWidget : widget pour MacOS

Et de l'autre côté:WinBouton, X11Bouton, etc. X11Menu, MacMenu, etc.

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

// Abstractionpublic abstract class Propriete { private double loyer; protected Propriete(double loyer) { this.loyer = loyer; } public double getLoyer() { return loyer; } public abstract double cout();}

// Implémentationpublic 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 Bridgepublic 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ériquepublic abstract class ProprieteImpl { public abstract double cout(double loyer);}// Implémentation concrètepublic 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.)

Programmation Objet en Java – Cours 9 Design Patterns 1 – (C) 2005, Frédéric Peschanski 14

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»

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 SimpleFactorypublic 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'AbstractFactorypublic 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émentationpublic class CliniqueDuPoleNord implements Clinique { ... public BebePhoque mettreBas(String nom) { return new BebePhoque(nom); }}...PoleNordClinique veto = ... ; // on a une maman phoqueBebePhoque 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

Le Design Pattern FactoryMethod (3/4)

Implémentationcf. TD

Variante SimpleFactoryMethod et utilité pour enlever les casts inutilesPar exemple dans le cas du clone:public class Cellule { ... public Object clone(Cellule souche) { // ici code du clonage }}

// code d'un client avec castCellule monClone = (Cellule) souche1.clone();

Programmation Objet en Java – Cours 9 Design Patterns 1 – (C) 2005, Frédéric Peschanski 25

Le Design Pattern FactoryMethod (4/4)

Implémentationcf. TD

Variante SimpleFactoryMethod et utilité pour enlever les casts inutilesPar 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 castCellule 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.

MotivationsProblème très général : on a un objet d'une classe Client qui veut utiliserun 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 puissefinalement 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