Transcript Utilisation des design patterns
MJ. Blin The design patterns
Design patterns Des modèles présentant des qualités particulières pour résoudre des problèmes fréquemment rencontrés en conception
Sommaire Qualités induites par les design patterns Utilisation des design patterns Classification des design patterns Des exemples de design patterns Bibliographie
The Design
Patterns,
James W.
Cooper
,
Addison http://www.patterndepot.com/put/8/JavaPatterns.htm
Wesley,
Design Patterns
, E. Gamma, R. Helm, R. Johnson, J. Vlissides, Addison-Wesley
Patterns in Java
, Mark Grand, Wiley
MJ. Blin The design patterns
Qualités induites par les design patterns
• la flexibilité par implantation d'algorithmes interchangeables, strategy par encapsulation de commandes, command • la réutilisabilité (par exemple, représentation des états d'un objet par des objets, mémento) • la manipulation aisée de grands nombres d'objets (par exemple, représentation d'un sous-système par un objet, facade) • la réutilisation par adaptation d'interfaces, adapter par composition, composite • l'indépendance avec les objets eux-mêmes (c'est-à-dire avec l'implémentation) en facilitant la manipulation d'interfaces (par exemple, builder)
MJ. Blin The design patterns
Qualités induites par les design patterns
(fin) • la facilitation de la conception de structures complexes d'objets à l'exécution • l'augmentation de la robustesse des applications en permettant : de créer un objet sans spécifier sa classe d’encapsuler des messages dans des objets d'éviter la dépendence matériel de l'application de cacher l'utilisation d'objets dont la représentation est susceptible de changer de cacher l'utilisation d'algorithmes susceptibles de changer de cacher des classes fortement couplées pour obtenir un système faiblement couplé d'effectuer une modification d'une classe dont on ne dispose pas du code source ou qui entraînerait la modification de plusieurs sous-classes
MJ. Blin The design patterns
Utilisation des design patterns
Pour la conception et la réalisation : • d'applications • de boite à outils (ensemble de classes réutilisables fournissant des services généraux, par exemple, un ensemble de classes pour gérer des listes, des piles, des tables,...
• de frameworks (conception réutilisables de squelettes d'application personnalisables)
MJ. Blin The design patterns
Utilisation des design patterns
(suite) Apports pour les applications Les design patterns améliorent : • la réutilisation interne grâce à : à l'isolation qui conduit à un faible couplage • la maintenabilité grâce à : l'indépendance avec le matériel l'isolation de sous-systèmes • l'extensibilité grâce à : l'utilisation de la composition pour étendre la hiérarchie de classes l'isolation de classes
MJ. Blin The design patterns
Utilisation des design patterns
(suite) Apports pour les boites à outils Les design patterns améliorent la facilité de réutilisation de code par l'augmentation de : • la flexibilité • l'applicabilité • l'efficacité
MJ. Blin The design patterns
Utilisation des design patterns
(fin) Apports pour les frameworks Un framework fournit l'architecture d'une application qui, elle, fournit le code des opérations.
Les design patterns améliorent la réutilisation de la conception par l'augmentation de : • la flexibilité • l'extensibilité • la documentation
MJ. Blin The design patterns
Des exemples de design patterns
Classification : • creational patterns exemples :builder, singleton • structural patterns exemples : adapter, composite, facade • behavioral patterns exemples : command, iterator, memento, observer, strategy
MJ. Blin The design patterns
Des exemples de patterns
• Builder Sépare la construction complexe de sa représentation d'un objet • Singleton Assure qu'une classe ne contient qu'une seule instance • Factory Retourne une instance de la classe appropriée pour traiter les données fournies en paramètres • Template Permet de définir un algorithme dans un classe et de laisser certains détails d'implémentation dans des sous-classes • Adapter Convertit l'interface d'une classe existante en une autre interface
MJ. Blin The design patterns
Des exemples de patterns
(suite) • Composite Permet d'utiliser les composants d'un objet complexe de la même façon qu'on utilise l'objet complexe dans son ensemble • Facade Permet d'utiliser les composants d'un objet complexe de la même façon qu'on utilise l'objet complexe dans son ensemble •Command Encapsule des messages dans des objets de façon à contrôler leur séquencement, gérer une queue, défaire,… • Iterator Moyen d’accès aux éléments d’un objet aggrégé indépendemment de l’objet lui-même • Memento Capture et externalise l’état interne d’un objet de façon à pouvoir le restaurer
MJ. Blin The design patterns
Des exemples de patterns
(fin) • Observer Quand un objet change d’état, tous ses dépendants en sont notifiés et sont mis à jour • Strategy Définit une famille d’algorithmes et permet à une application d’utiliser l’un ou l’autre algorithme indifféremment • Visitor Crée des classes qui traitent d'un ensemble d' instances de manière spécifique
MJ. Blin The design patterns
Builder Sépare la construction d'un objet complexe de sa représentation
Structure Director construct ( ) structure 1..*
Builder buildPart ( )
for all structure structure.builPart () ConcreteBuilder buildPart () getResult () L'instance de la classe Director sera configurée de façon à être liée aux instances convenables de la classe ConcreteBuilder
MJ. Blin The design patterns
Builder
(suite) Example : convertisseur de format RTF - ASCII RTF - LateX RTF - TexWidget ...
Builders Director RTFReader parseRTF ( …)
TextConverter
static TextConverter getInstance(dest)
convertCharacter (char) convertFontChange (font) convertParagraph ()
ASCIIConverter convertCharacter (char) convertFontChange (font) convertParagraph () TeXConverter convertCharacter (char) convertFontChange (font) convertParagraph () TextWidgetConverter convertCharacter (char) convertFontChange (font) convertParagraph () Selon la conversion à faire, l'objet RTFReader sera lié à l'objet ASCIIConverter ou bien à l'objet TeXConverter ou bien à l'objet TextWidgetConverter Il est aisée d'ajouter un nouveau format de conversion. Il suffit d'ajouter une nouvelle sous-classe de TextConverter et d'implémenter les opérations adéquates
MJ. Blin The design patterns
Builder
(suite) Java
class RTFReader
…..
…..
…..
…..
{ void parseRTF (String mode, String Texte) TextConverter converter=TextConverter.getInstance(mode); converter.convertParagraph(); converter.convertCharacter(); converter.convertFontChange(); } // fin de la methode parseRTF } // fin de la classe RTFReader
abstract class TextConverter
static TextConverter getInstance (String dest) { switch (dest) { case "ACSII" return new ACSIIConverter (); case "TeX" return new TeXConverter (); case "TWC" return new TeXWidgetConverter (); default return null; } // fin du switch { abstract void convertCharacter (char c) { } // fin de la méthode abstract void convertFontChange (font f) { } // fin de la méthode abstract void convertParagraph () { } // fin de la méthode } // fin de la classe TextConverter
MJ. Blin The design patterns
Builder
(fin)
class ACSIIConverter
void convertCharacter (char c) { ……..
extends TextConverter { } // fin de la méthode void convertFontChange (font f) { ……..
} // fin de la méthode void convertParagraph () { ……..
} // fin de la méthode } // fin de la classe ASCIIConverter
class TeXConverter
…..
{
Class TeXWidgetConverter
…..
{
MJ. Blin The design patterns
Singleton Assure qu'une classe ne contient qu'une seule instance
Structure Singleton static uniqueInstance ...
static Singleton Singleton () getSingleton () ...
return uniqueInstance Le constructeur teste si uniqueInstance est vide. Si oui, il crée une instance, enregistre le pointeur vers cette instance dans uniqueInstance et retourne le contenu de uniqueInstance.
Si une instance existe déjà, il retourne le contenu de uniqueInstance.
MJ. Blin The design patterns
Singleton
(suite) Exemple : AudioClipManager static uniqueInstance prevClip : AudioClip audioClipManager () getAudioClipManager () play (AudioClip clip) stop () AudioClip play () stop () La classe AudioClipManager est un singleton. Elle s'assure qu'un seul clip est joué en même temps.
L'opération play (AudioClip clip) teste si prevClip est vide. Si oui ,elle lance l'opération play sur le clip à jouer et met à jour prevClip Si non, elle stoppe l'instance de AudioClip référencée par prevClip, lance l'opération play () sur le nouveau clip à jouer et met à jour prevClip
MJ. Blin The design patterns
Singleton
(fin) Java
public class ClassPrincipale
while (commande!="") { commande=readClavier() } // fin du while { public static void main (String args[]){ String commande="demarrage"; AudioClipManager manager=new AudioClipManager() ; AudioClip clip=new AudioClip(commande); manager.playClip(clip); } // fin de l'opération main private String readClavier () {…} } // fin de classPrincipale
class AudioClipManager
{ static AudioClipManager uniqueInstance=null; AudioClip prevClip=null; AudioClipManager AudioClipManager () { if (uniqueInstance==null) { uniqueInstance=this; } // fin du if return uniqueInstance; } // fin du constructeur public playClip (AudioClip clip) { if (prevClip!=null) prevClip.stop(); prevClip= clip; prevClip.play(); } // fin de l'opération playClip } // fin de la classe AudioManager
MJ. Blin The design patterns
Factory Retourne une instance de la classe appropriée pour traiter les données fournies en paramètres
Structure
classe abstraite
Factory namer (...) ClasseConcrète A ClasseConcrète B if (namer= ...) return new ClasseConcreteA(); else return new ClasseConcreteB() ;
MJ. Blin The design patterns
Factory
(suite) 1..* Exemple : Livre titre résumé 1..*
Recherche
Vector livres Recherche () 1..* Factory FactoryRecherche définitRecherche () RechercheParAuteur RechercheParAuteur () 1..* Auteur String nomAuteur getNomAuteur() retourneLivres() RechercheParTheme RechercheParTheme () 1..* Thème String theme getTheme() retourneLivres()
MJ. Blin The design patterns
Factory
(suite) classe Recherche { protected Vector livresRetournes=new Vector(); public Vector Recherche () { return livresRetournes; } // fin de la methode recherche } // fin de la classe Recherche class RechercheParAuteur extends Recherche { private Vector auteurs=new Vector(); public void ajoutAuteur (Auteur a) { auteurs.addElement(a); } // fin de la methode ajoutAuteur public RechercheParAuteur (String critère) { int i=0; while (auteurs(i).getNomAuteur()!=critere && i MJ. Blin The design patterns (fin) class FactoryRecherche { public Recherche definitRecherche (string type, string critere ) { if (type=="auteur") {return new RechercheParAuteur(critere);} else {return new RechercheParAuteur (critere);} } // fin de la methode definitRecherche } // fin de la classe factoryRecherche class application { public static void main (String args[]){ private string type=args(1); private string critere=args(2); protected Vector livres=new Vector(); FactoryRecherche f=new FactoryRecherche (); recherche r=f.definitRecherche (type, critere); livres=r.recherche(); for (i=0;i MJ. Blin The design patterns classe abstraite SousClasse A SousClasse B MJ. Blin The design patterns (suite) Exemple : PageAccueil dessiner() PanelLogo() AccueilEtudiant PanelMenu() AccueilEntreprise PanelMenu() MJ. Blin The design patterns (suite) class Application { public static void main (String args[]){ private int statut=0; //affiche une fenetre de login ……… // recherche le login et récupère le statut de l'utilisateur ……… // si statut=1 il s'agit d'un etudiant, // si statut=2 c'est une entreprise if (statut==1) {AccueilEtudiant f= new AccueilEtudiant()} } if (statut==2) {AccueilEntreprise f=new AccueilEntreprise()} ……….. } // fin du main } // fin de la classe Application class PageAccueil extends Jframe { public PageAccueil() { // creation de la fenetre f ………… panelLogo(); panelMenu(f); //programmation des listeners ………. } // fin du constructeur public panelLogo() { /* creation d'un panel contenant le logo Dauphine et placement dans la fenetre f */ …………… } // fin de la methode panelLogo } // fin de la classe PageAccueil MJ. Blin The design patterns (fin) class AccueilEtudiant extends PageAccueil { public AccueilEtudiant() { super(); } // fin du constructeur public void panelMenu (PageAccueil f) { /*programmaton du menu etudiant et placement dans la fenetre passee en parametre*/ …… } // fin de la methode panelMenu } // fin de la classe AccueilEtudiant class AccueilEntreprise extends PageAccueil { public AccueilEntreprise() { super(); } // fin du constructeur public void panelMenu (PageAccueil f) { /*programmaton du menu entreprise et placement dans la fenetre passee en parametre*/ …… } // fin de la methode panelMenu } // fin de la classe AccueilEntreprise MJ. Blin The design patterns Structure Target request () Adaptee specificRequest () Adapter request () adaptee.specificRequest () La classe existante Adaptee possède une opération specificRequest. Mais, l'application exécute l'opération request. Aussi La sous-classe Adapter de la classe Target implémente l'opération request de façon à cacher la vraie interface de la classe Adaptee. MJ. Blin The design patterns (suite) Exemple : Shape boundingBox () Textview getExtent () Line boundingBox () Text boundingBox () Textview.getExtent () Ce modèle permet à une application et la classe existante Textview de communiquer alors que ce n'était pas prévu. L'application appelle l'opération boundingBox sur un objet de la classe Text. Cette opération redirige l'appel en appellant l'opération getExtent sur l'objet de la classe Textview MJ. Blin The design patterns (fin) Java public class ClassPrincipale public static void main (String args[]){ Shape monObjet=null; { …….. monObjet = new Text (); monObjet.boundingBox (); } // fin de classPrincipale interface Shape { void boundingBox (); } // fin de l'interface Shape class Text ….. implements Shape { void boundingBox () TextView t=new TextView (); t.getExtent (); } // fin de la méthode boundingBox } // fin de la classe Text MJ. Blin The design patterns Structure Component getParent () ... 1..* children Feuille operation () ... Composite add (Component) remove (Component) getChild (Component) operation () ... for all g in children g.operation () L'application exécute les mêmes opérations sur tous les composants qu'ils soient simples (Feuille) ou composés (Composite) MJ. Blin The design patterns (suite) Exemple PlanningElement getDurée ():int getParent():Activite 1..* children Tâche getDurée():int Jalon getDuree ():int Activité addChild (PlanningElement) removeChild (PlanningElement) getChild (int):PlanningElement getDurée ():int ActivitéFormation ActivitéDéveloppement ActivitéOrganisation MJ. Blin The design patterns (suite) Java abstract class PlanningElement Activite parent; { public Activite getParent() { return parent; } // fin de la methode getParent public abstract getDuree () { } // fin de la methode getDuree } // fin de la classe PlanningElement abstract class Activite extends PlanningElement { private Vector children=new Vector (); public PlanningElement getChild (int index) { return (PlanningElement) children.elementAt(index); } // fin de la méthode getChild public void addChild (PlanningElement child) { children.addElement (child); child.parent=this; } // fin de la methode addChild public removeChild (PlanningElement child) { children.removeElement(child); } // fin de la methode removeChild public int getDuree() { int duree=0; for (int i=0;i MJ. Blin The design patterns (fin) public class Tache extends int dateDebut=null; int dateFin=null; PlanningElement { public Tache (int date1, int date2) { dateDebut=date1; dateFin=date2; ........ } // fin du constructeur public int duree() { return dateFin-dateDebut; } // fin de la methode duree } // fin de la classe Tache public class Jalon extends int dateJalon=null; PlanningElement { public Jalon (int date1) { dateJalon=date1; ........ } // fin du constructeur public int duree() { return 1; } // fin de la methode duree } // fin de la classe Jalon MJ. Blin The design patterns Facade Facade connaît : • les classes du sous-système • délègue (après éventuelle transformation) les demandes de l’application aux “bons” objets du sous-système Les classes du sous-système : • implémentent les fonctionnalités du sous-système • n’ont pas connaissance de la classe Facade MJ. Blin The design patterns (suite) Exemple Application MessageFacade MessageFacade (String to, String from, String subject) setCorps (String messageBody) addAttachement (Object attach) setSignature (String sign) envoyer () Corps Attachement 0..1 0..* Signature Message 0..1 String to String from String sujet 0..1 EnvoiMessage Pour créer un message puis l’envoyer, l’application crée un objet MessageFacade. Toutes les opérations exécutées par l’application le seront sur cet objet. Les classes et objets du sous-système sont complétement masqués à l’application MJ. Blin The design patterns (suite) Java public class Application { public void constitueMessage () String to="etudiants"; String from="MJ. Blin"; String sujet="le pattern facade"; MessageFacade message=new MessageFacade (to, from, sujet); message.setCorps ("Pour créer un message puis l’envoyer, l’application crée un objet MessageFacade"); message.setSignature("Marie-Jose Blin"); message.envoyer(); } // fin de la methode constitueMessage } // fin de la casse Application import systemeMessagerie.*; public class MessageFacade { Message monMes; public MessageFacade (String to, String from, String sujet) { monMes=new Message (to, from, sujet) } // fin du constructeur public setCorps (String messageBody) { monMes.body=new Corps (messageBody); } // fin de la methode setCorps public setSignature(String signature) { monMes.nom=new Signature(signature); } // fin de la methode setSignature public envoyer () { monMes.envoi=new EnvoiMessage(monMes); } // fin de la methode envoyer } // fin de la classe MessageFacade MJ. Blin The design patterns (fin) package systemeMessagerie class Message { String to; String from; String sujet; Corps body; Signature nom; EnvoiMessage envoi; public Message (String a, String de, String pour) { this.to=a; this.from=de; this.sujet=pour; } // fin du constructeur } // fin de la classe Message class Corps { String body; public Corps (String c) { body=c; } // fin du constructeur } // fin de la classe Corps class Signature { String nom; public Signature (String s) { nom=s; } // fin du constructeur } // fin de la classe Signature class EnvoiMessage …….. { public EnvoiMessage (Message m) { // constitution du protocole SMTP par consultation du message m // envoi du message …….. } // fin du constructeur } // fin de la classe EnvoiMessage MJ. Blin The design patterns Structure Application 1..* Receiver action () receiver 1..* Invoker receiver.action () Command execute () ConcreteCommand execute () L’application lie chaque objet Invoker à un objet ConcreteCommand. La classe ConcreteCommand implémente l’opération execute (). Cette opération lance l’opération action sur l’objet Receiver auquel il est lié. La classe Receiver implémente effectivement l’action. Elle appartient à l’application. MJ. Blin The design patterns (suite) Exemple Application Fenetre Menu add (MenuItem) Invoker 1..* MenuItem clicked () Document open () close () cut () copy () paste () Receiver receiver receiver.paste () execute () Command execute () PasteCommand ConcreteCommand ... Implantation des commandes de menu d’un éditeur de texte. Chaque objet MenuItem est lié à un objet ConcreteCommand (ici PasteCommand, …). Ces sous classes implémentent l’opération exécute () en lançant l’opération correspondante sur l’objet Document lié. MJ. Blin The design patterns (suite) Java class Application extends Frame { Document d=new Document(); public static void main (String args[]) { Menu itemAction=new Menu ("File"); MenuItem subItemOpen = new CommandOpen(d); itemAction.add(subItemOpen); MenuItem subItemClose = new CommandClose(d); itemAction.add(subItemClose); ….. subItemOpen.addActionListener (new Action()); subItemClose.addActionListener (new Action()); ….. } // fin de la methode main public Document getDocument() { return d; } // fin de la methode getDocument public initDocument() { d=null; } // fin de la methode initDocument class Action implements ActionListener { public void ActionPerformed (ActionEvent e) { Command cmd=(Command) e.getSource(); cmd.execute(); } // fin de la methode ActionPerformed } // fin de la classe Action } // fin de la classe Application MJ. Blin The design patterns (fin) interface Command { public void execute() {} } // fin de l'interface Command class CommandeOpen extends MenuItem implements Command { Document monDocument=null; public CommandeOpen (Document d) { super("open"); monDocument=d; } // fin du constructeur public void execute () { monDocument.open(); } // fin de la methode Execute } // fin de la classe CommandeOpen class CommandeClose extends MenuItem implements Command { Document monDocument=null; public CommandeClose (Document d) { super("close"); monDocument=d; } // fin du constructeur public void execute () { monDocument.close(); } // fin de la methode Execute } // fin de la classe CommandeClose MJ. Blin The design patterns Structure Aggregate createIterator () 1..* Application 1..* Iterator first () next () isDone () currentItem () ConcreteAggregate createIterator () 1..* ConcreteIterator return new ConcretIterator (this) Plusieurs objet ConcreteIterator peuvent être associés au même objet ConcreteAggregate si on veut parcourir l’objet aggrégé de différentes façons MJ. Blin The design patterns (suite) Exemple Aggregate AbstractList createIterator () count () append (Item) remove (Item) ... 1..* Application 1..* Iterator first () next () isDone () currentItem () FilteredList ConcreteAggregate SkipList ConcreteAggregate FilteringIterator ConcreteIterator SkipListIterator ConcreteIterator Deux classes de listes sont définies : FilteredList et SkipList. Chaque liste créée est associée à un objet Iterator appartenant à la classe correspondante au moyen d’accès approprié. MJ. Blin The design patterns (suite) Java public class Application { public void gereListe () { FilteredList maListe=new FilteredList(); Iterator it=(Iterator) maListe.createIterator(); ….. Item i=it.first() Item i=it.next(); Item i=it.currentItem(); boolean fin=it.isDone(); ….. } // fin de la methode gereListe } // fin de la classe Application public interface Iterator { public Item first (); public Item next (); public boolean isDone (); public Item currentItem (); } // fin de l'interface Iterator public interface AbstractList public Iterator createIterator (); public int count (); { public void append (Item i); public void remove (Item i); } // fin de l'interface AbstractList MJ. Blin The design patterns (fin) public class FilteredList implements AbstractList { ….. public Iterator createIterator () { ... return new FilteringIterator(); } // fin de la methode createIterator } // fin de la classe FilteredList class FilteringIterator public Item first() { ….. implements Iterator { } // fin de la methode first public Item next() { ….. } // fin de la methode next public boolean isDone() { ….. } // fin de la methode isDone public Item currentItem() { ….. } // fin de la methode currentItem } // fin de la classe FilteringIterator MJ. Blin The design patterns (ou Snapshot ou State) Structure : Originator state setMemento (Memento m) createMemento () Memento state getState () setState () CareTaker return new Memento (state) state=m.getState() aCareTaker createMemento () anOriginator aMemento new Memento setState () setMemento (aMemento) getState () MJ. Blin The design patterns (suite) Exemple : Originator ElementGraphique xDebut yDebut xFin yFin couleur setMemento (Memento) createMemento ():Memento dessine () Memento xDebut yDebut xFin yFin couleur getState () setState () CareTaker Action deplace (ElementGrahique, real, real) changeDimension ( ElementGraphique, real, real, real, real) changeCouleur( ElementGraphique, Couleur) defaire (ElementGraphique) Rectangle Cercle Ligne Les opérations déplace, changeCouleur et changeDimension de l’objet Action suscite la création d’un objet Mémento de façon à conserver l’état de l’élément graphique avant l’exécution de l’action. L’opération défaire peut ainsi faire reprendre à l’élémentGraphique son état antérieur. Comme tous les états antérieurs sont conservés systématiquement, toutes les actions effectuées peuvent être ainsi défaites successivement. MJ. Blin The design patterns (suite) Java class Action { private Vector states=new Vector(); void deplace (ElementGraphique e, real x, real y) { sauveEtat(e); e.setxDebut(x); e.setyDebut(y); // recalcul de xFin et de yFin ..... e.dessine(); } // fin de la methode deplace void changeDimension (ElementGraphique e, real x1, real y1, real x2, real y2) { sauveEtat(); e.setxDebut(x1); e.setyDebut(y1); e.setxFin(x2); e.setyFin(y2); e.dessine(); } // fin de la methode changeDimension void changeCouleur (ElementGraphique e, Color c) { sauveEtat(); e.setCouleur(c); e.dessine(); } // fin de la methode deplace void defaire (ElementGraphique e) { int nbreEtats=states.size(); Memento s= state.elementAt(nbreEtats-1); states.removeElement(nbreEtats-1); e.setMemento(s); e.dessine(); } // fin de la methode defaire void sauveEtat (ElementGraphique e) { Memento s=e.createMemento(); states.addElement (s); } // fin de la methode sauveEtat } // fin de la classe Action MJ. Blin The design patterns Class ElementGraphique ..... { Memento createMemento () { Memento m=new Memento () m.setState(this); return m; } // fin de la methode createMemento void setMemento (Memento m) { Vector v=m.getStates(); xDebut=v.elementAt(0); yDebut=v.elementAt(1); xFin=v.elementAt(2); yFin=v.elementAt(3); couleur=v.elementAt(4); } // fin de la methode setMemento void setxDebut (real x) { xDebut=x; } // fin de la methode setxDebut ….. } // fin de la classe ElementGraphique class Memento { Vector state=new Vector(); void setState(ElementGraphique e) { state(0)=e.getxDebut(); state(1)=e.getyDebut(); state(2)=e.getxFin(); state(3)=e.getyFin(); state(4)=e.getCouleur(); } // fin de la methode setState Vector getState () { return state; } // fin de la methode getState } // fin de la classe Memento MJ. Blin The design patterns Structure Subject attach (Observer) detach (Observer) notify () subject for all o in observer o.update () ConcreteSubject subjectState getState () setState () 1..* observer Observer update () return subjectState ConcreteObserver observertState update () observerState = subject.getState () Chaque objet ConcreteSubject peut être associé à plusieurs objets ConcreteObserver. Quand il change d’état, son opération “notify” lance l’opération “update” sur tous ses objets associés qui se mettent alors à jour. MJ. Blin The design patterns (suite) Exemple : Subject Résultats attach (Presentation) notifyObservers () subject 1..* observer Observer Présentation notify () RésultatsDesVentes attach (Presentation) notifyObservers() ConcreteSubject ListeDeNombres notify () Camembert notify () ConcreteObserver ConcreteObserver Histogramme notify () ConcreteObserver Les résultats peuvent être affichés de trois manières différentes. Lorsque un objet Résultats est modifié, il en notifie ses objets associés Présentation qui se mettent à jour. MJ. Blin The design patterns (suite) Java class classPrincipale { public static void main (String args[]){ Resultats res= (Resultats) new ResultatsDesVentes(); ListeDeNombres p1=new ListeDeNombres(res); Camembert p2=new Camembert(res); Histogramme p3=new Histogramme (res); } // fin de la methode main } // fin de classPrincipale abstract class Presentation Resultats sujet; { public Presentation (Resultats r) { r.attach (this); sujet=r; } // fin du constructeur public void notify (String s, sujet) ( } // fin de la methode notify } // fin de la classe Presentation class ListeDeNombres extends Presentation { public ListedeNombres (Resultats r) { super(r) } // fin du constructeur void notify (String s, Resultats r) { Vector chiffres = r.chiffresMois(s) /*affichage de la liste des chiffres recus dans le vecteur chiffres */ ….. } // fin de la methode notify } // fin de la classe ListeDeNombres MJ. Blin The design patterns abstract class Resultats { private Vector observers=new Vector(); public void attach (Presentation s) { observers.addElement (s); } // fin de la methode attach public void notifyObservers (String s) { for(i=0;i class ResultatsDesVentes extends Resultats implements ItemListener { public ResultatsDesVentes () { /* affiche une fenetre avec un radio bouton par mois de l'annee */ ….. } // fin du constructeur public void itemStateChanged (ItemEvent e) { if (e.getStateChanged()==ItemEvent.SELECTED){ JRadioButton selection=(JRadioButton) e.getSource(); notifyObservers(selection.paramString());} } // fin de la methode itemStateChanged public Vector chiffresMois(String s) { Vector chiffres=new Vector (); /* recuperation des chiffres du mois indiqué par le parametre s */ ….. return chiffres; } // fin de la methode chiffresMois } // fin de la classe ResultasDesVentes MJ. Blin The design patterns Context contextInterface () strategy Strategy algorithmInterface () ConcreteStrategyA algorithmInterface () ConcreteStrategyB algorithmInterface () strategy.algorihtmInterface () L’objet Context est lié à l’objet ConcreteStrategy correspondant à l’algorithme L’opération contextInterface lance l’exécution de l’algorithme ainsi choisi. qui convient. MJ. Blin Exemple : Context AfficheCharges afficheChargesEmp () The design patterns (suite) implantation Strategy ChargesEmp calcul () ChargesEmpF ChargesEmpGB ChargesEmpI calcul () calcul () calcul () ConcreteStategy ConcreteStategy ConcreteStategy implantation.calcul () Une application de paie doit être installée en France, en Grande Bretagne et en Italie. Le calcul des charges employé est différent selon les pays. Suivant le pays dans lequel l’application est installé, l’objet AfficheCharges est configuré de façon à être lié à l’objet implantant l’algorithme adéquat de calcul des charges. MJ. Blin The design patterns (fin) Java class AfficheCharges extends Frame { private ChargesEmp algo; public AfficheCharges (Employe e) { super (); switch (e.getType()) { case 1 : algo=new ChargesEmpF(e); case 2 : algo=new ChargesEmpGB(e); case 3 : algo=new ChargesEmpI(e); default : algo=new ChargesEmpF(e); } // fin du switch } // fin du constructeur public afficheChargesEmp (Employe e) { String [] tableauDesCharges=algo.calcul(e); …….. } // fin de la methode afficheChargesEmp } // fin de la classe AfficheCharges public interface ChargesEmp { public String [] calcul(Employe e) } // fin de la méthode calcul } // fin de l'interface ChargesEmp public class ChargesEmpF implements ChargesEmp { public String[] calcul (Employe e) private String [] resultats= new String[10]; ….. return resultats; } // fin de la methode calcul } // fin de la classe ChargesEmpF ….. MJ. Blin The design patterns VisitedClasse accept () Visitor.visit () AbstractVisitor visit () ConcreteVisitorA visit () ConcreteVisitorB visit () application accept (c) VisitedInstance c:ConcreteVisitor visit (this) MJ. Blin The design patterns (suite) 1..* Offre duree accept (VisitorOffre v) OffreALEtranger niveauEtudesRequis accept (VisitorALEtranger v) Visitor visit (Offre o) VisitorOffre visit (Offre o) VisitorALEtranger visit (Offre o) visit (OffreALEtranger e) MJ. Blin The design patterns (suite) public class Offre { int duree ; public Offre (int d) {duree=d;} public int getDuree () {return duree;} public void accept (Visitor v) {v.visit(this);} } // fin de la classe Offre public class OffreALEtranger extends Offre { int niveauEtudesRequis; public OffreALetranger (int d, int n) { duree=d; niveauEtudesRequis=n; } // fin du constructeur public int get niveauEtudesRequis() { return niveauEtudesRequis } // fin de la methode getNiveauEtudesRequis } // fin de la classe OffreALEtranger public abstract class Visitor { public abstract void visit (Offre o); public abstract void visit (OffreALEtranger e); } // fin de la clsse Visitor MJ. Blin The design patterns (suite) public class VisitorOffre extends Visitor { protected float dureeMoyenne; protected int nombre; public VisitorOffre() {dureeMoyenne=0; nombre=0;} public void visit (Offre o) { DureeMoyenne=(dureeMoyenne*nombre+o.getDuree)/ (nombre+1) nombre+=1; } // fin de la methode visit public float getDureeMoyenne () {return dureeMoyenne;} } // fin de la classe VisitorOffre public class VisitorOffreALEtranger extends Visitor { protected float niveauMoyen; protected int nombre; public VisitorOffreALEtranger() {niveauMoyen=0; nombre=0;} public void visit (OffreALEtranger e) { niveauMoyen=niveauMoyen*nombre+e.getNiveau)/ (nombre+1) nombre+=1; } // fin de la methode visit public void visit (Offre o) {} public float getNiveauMoyen () {return niveauMoyen;} } // fin de la classe VisitorOffreALEtranger MJ. Blin The design patterns (fin) class Application { public static void main (String args[]){ Vector offres=new vector(); /* remplissage du vecteur offres par les references aux objets offres. ……………… VisitorOffre v=new VisitorOffre(); VisitorOffreALEtranger ve=new VisitorOffreAletranger(); for (i=0; iFactory
Template Permet de définir un algorithme dans un classe et de laisser certains détails d'implémentation dans des sous-classes
Template
Template
Template
Adapter Convertit l'interface d'une classe existante en une autre interface
Adapter
Adapter
Composite Permet d'utiliser les composants d'un objet complexe de la même façon qu'on utilise l'objet complexe dans son ensemble
Composite
Composite
Composite
Facade Fournit une interface unique à l’ensemble des interfaces d’un sous-système de façon à réduire les communications entre sous systèmes
Facade
Facade
Facade
Command Encapsule des messages dans des objets de façon à contrôler leur séquencement, gérer une queue, défaire,...
Command
Command
Command
Iterator Moyen d’accès aux éléments d’un objet aggrégé indépendemment de l’objet lui-même
Iterator
Iterator
Iterator
Memento
Capture et externalise l’état interne d’un objet de façon à pouvoir le restaurer
Memento
Memento
Observer Quand un objet change d’état, tous ses dépendants en sont notifiés et sont mis à jour
Observer
Observer
Strategy Définit une famille d’algorithmes et permet à une application d’utiliser l’un ou l’autre algorithme indifféremment
Strategy
Strategy
Visitor Crée des classes qui traitent d'un ensemble d' instances de manière spécifique
Visitor
Visitor
Visitor
Visitor