MJ. BlinThe design patterns Design patterns Des modèles présentant des qualités particulières...
-
Upload
eugene-girard -
Category
Documents
-
view
108 -
download
2
Transcript of MJ. BlinThe design patterns Design patterns Des modèles présentant des qualités particulières...
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
Bibliographie
The Design Patterns, James W. Cooper, Addison Wesley, http://www.patterndepot.com/put/8/JavaPatterns.htm
Design Patterns, E. Gamma, R. Helm, R. Johnson, J. Vlissides, Addison-Wesley
Patterns in Java, Mark Grand, Wiley
Sommaire
Qualités induites par les design patterns
Utilisation des design patternsClassification des design patternsDes exemples de design patterns
MJ. Blin The design patterns
• la flexibilitépar implantation d'algorithmes interchangeables, strategypar 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éutilisationpar adaptation d'interfaces, adapterpar 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)
Qualités induites par les design patterns
MJ. Blin The design patterns
• 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
Qualités induites par les design patterns(fin)
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)
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
Apports pour les applications
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 patternsexemples :builder, singleton
• structural patternsexemples : adapter, composite, facade
• behavioral patternsexemples : command, iterator, memento, observer, strategy
MJ. Blin The design patterns
Des exemples de patterns
• BuilderSépare la construction d'un objet
complexe de sa représentation
• SingletonAssure qu'une classe ne contient qu'une seule instance
• FactoryRetourne une instance de la classe appropriée pour traiter les données fournies en paramètres
• TemplatePermet de définir un algorithme dans un classe et de laisser certains détails d'implémentation dans des sous-classes
• AdapterConvertit l'interface d'une classe existante en une autre interface
MJ. Blin The design patterns
• 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
•CommandEncapsule des messages dans des objets de façon à contrôler leur séquencement, gérer une queue, défaire,…
• IteratorMoyen d’accès aux éléments d’un objet aggrégé indépendemment de l’objet lui-même
• MementoCapture et externalise l’état interne d’un objet de façon à pouvoir le restaurer
Des exemples de patterns(suite)
MJ. Blin The design patterns
• 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
Des exemples de patterns
(fin)
MJ. Blin The design patterns
Builder
Structure
Directorconstruct ( )
BuilderbuildPart ( )
ConcreteBuilderbuildPart ()getResult ()
for all structurestructure.builPart ()
L'instance de la classe Director sera configurée de façon à être liée aux instances convenables de la classe ConcreteBuilder
Sépare la construction d'un objet complexe de sa représentation
structure
1..*
MJ. Blin The design patterns
Builder(suite)
Example : convertisseur de format RTF - ASCIIRTF - LateXRTF - TexWidget...
RTFReaderparseRTF ( …)
TextConverterstatic TextConverter getInstance(dest) convertCharacter (char)convertFontChange (font)convertParagraph ()
ASCIIConverterconvertCharacter (char)convertFontChange (font)convertParagraph ()
TeXConverterconvertCharacter (char)convertFontChange (font)convertParagraph ()
TextWidgetConverterconvertCharacter (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
Director
Builders
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
class ACSIIConverter extends TextConverter {void convertCharacter (char c) {……..} // 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 {…..
Builder(fin)
MJ. Blin The design patterns
Singleton
Assure qu'une classe ne contient qu'une seule instance
Structure
Singletonstatic 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 :
AudioClipManagerstatic uniqueInstanceprevClip : 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
Java
public class ClassPrincipale {public static void main (String args[]){String commande="demarrage";while (commande!="") {
AudioClipManager manager=new AudioClipManager() ; AudioClip clip=new AudioClip(commande);manager.playClip(clip);commande=readClavier()
} // fin du while} // 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 ifreturn 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
Singleton(fin)
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
ClasseConcrète A ClasseConcrète B
Factorynamer (...)
if (namer= ...) return new ClasseConcreteA();else return new ClasseConcreteB() ;
MJ. Blin The design patterns
Exemple :
RechercheFactoryRecherche
définitRecherche ()
Livre
titrerésumé
RechercheParTheme
1..*
Vector livres
Factory(suite)
Auteur
getNomAuteur()retourneLivres()
String nomAuteur
1..*
Thème
getTheme()retourneLivres()
String theme
1..*
1..* 1..*
RechercheParAuteur
RechercheParAuteur () RechercheParTheme ()
Recherche ()
Factory
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<auteurs.size()) {
auteurs(i).getNomAuteur();} //if (i<auteurs.size()){
livresRetournes=auteurs(i).retourneLivres();} // fin de la methode recherche
} // fin de la classe RechercheParAuteur
class RechercheParTheme extends Recherche { private Vector themes=new Vector();
public void ajoutTheme (Theme t) {themes.addElement(a); } // fin de la methode ajoutTheme
public RechercheParTheme (String critère) { int i=0;while (themes(i).getTheme()!=critere && i<themes.size()) { themes(i).getTheme();} // fin du whileif (i<themes.size()){ livresRetournes=themes(i).retourneLivres();} // fin de la methode recherche
} // fin de la classe RechercheParTheme
MJ. Blin The design patterns
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<livres.size();i++) {
System.out.println (livres(i).getTitre));} // fin du for
} // fin du main} // fin de la classe application
Factory(fin)
MJ. Blin The design patterns
Permet de définir un algorithme dans un classe et de laisser certains détails d'implémentation dans
des sous-classes
Template
classe abstraite
SousClasse A SousClasse B
MJ. Blin The design patterns
Template(suite)
Exemple :
PageAccueil
AccueilEtudiant AccueilEntreprise
dessiner()PanelLogo()
PanelMenu() PanelMenu()
MJ. Blin The design patterns
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 entrepriseif (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
Template(suite)
MJ. Blin The design patterns
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
Template(fin)
MJ. Blin The design patterns
Adapter
Convertit l'interface d'une classe existante en une autre interface
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
Adapter(suite)
Exemple :
Shape
boundingBox ()
Textview
getExtent ()
TextLine
boundingBox () 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
Adapter(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
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
Structure
Component
getParent ()...
Feuille
operation ()...
Compositeadd (Component)remove (Component)getChild (Component)operation ()...
for all g in childreng.operation ()
children
L'application exécute les mêmes opérations sur tous les composants qu'ils soient simples (Feuille) ou composés (Composite)
1..*
MJ. Blin The design patterns
Composite(suite)
Exemple
PlanningElement
getDurée ():int
getParent():Activite children
JalongetDuree ():int
Activité
addChild (PlanningElement)removeChild (PlanningElement)getChild (int):PlanningElement getDurée ():int
ActivitéOrganisationActivitéDéveloppementActivitéFormation
TâchegetDurée():int
1..*
MJ. Blin The design patterns
Composite(suite)
Javaabstract 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<children.size();i++) {
inc=children.elementAt(i).getDuree();duree+=inc;
} // fin du forreturn duree;
} // fin de la methode getDuree
} // fin de la classe Activite
MJ. Blin The design patterns
public class Tache extends PlanningElement {int dateDebut=null;
int dateFin=null;
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 PlanningElement {int dateJalon=null;
public Jalon (int date1) {dateJalon=date1;........
} // fin du constructeur
public int duree() {return 1;
} // fin de la methode duree
} // fin de la classe Jalon
Composite(fin)
MJ. Blin The design patterns
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 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
Facade(suite)
Exemple
Application
MessageFacade
Corps Attachement Signature Message
String toString fromString sujet
0..*
EnvoiMessage
MessageFacade (String to, String from, String subject)setCorps (String messageBody)addAttachement (Object attach)setSignature (String sign)envoyer ()
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
0..10..10..1
MJ. Blin The design patterns
Facade(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
package systemeMessagerieclass 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
Facade(fin)
MJ. Blin The design patterns
Encapsule des messages dans des objets de façon à contrôler leur séquencement, gérer une
queue, défaire,...
Command
Structure
Application Invoker
execute ()
Command
ConcreteCommand
execute ()
Receiveraction ()
1..*
receiver
receiver.action ()
1..*
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
Command(suite)
Exemple
Fenetre MenuItem
execute ()
Command
PasteCommand
execute ()
Documentopen ()close ()cut ()copy ()paste ()
receiver
receiver.paste ()
1..*Menu
clicked ()add (MenuItem)
...
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é.
Invoker
Receiver
ConcreteCommand
Application
MJ. Blin The design patterns
Command(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
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
Command(fin)
MJ. Blin The design patterns
Iterator
Moyen d’accès aux éléments d’un objet aggrégé indépendemment de l’objet lui-même
Structure
Aggregate
createIterator ()
Application Iterator
first ()next ()isDone ()currentItem ()
ConcreteAggregate
createIterator ()ConcreteIterator
1..* 1..*
return new ConcretIterator (this)
1..*
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
Iterator(suite)
AbstractList
createIterator ()count ()append (Item)remove (Item)...
ApplicationIterator
first ()next ()isDone ()currentItem ()
1..* 1..*
Exemple
SkipList
FilteredList FilteringIterator
SkipListIterator
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é.
Aggregate
ConcreteAggregate
ConcreteAggregate
ConcreteIterator
ConcreteIterator
MJ. Blin The design patterns
Iterator(suite)
Javapublic 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
public class FilteredList implements AbstractList { ….. public Iterator createIterator () {
return new FilteringIterator(); } // fin de la methode createIterator ...} // fin de la classe FilteredList
class FilteringIterator implements Iterator { public Item first() {
….. } // 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
Iterator(fin)
MJ. Blin The design patterns
Memento (ou Snapshot ou State)
Capture et externalise l’état interne d’un objet de façon à pouvoir le restaurer
Structure :
Originator
setMemento (Memento m)createMemento ()
state
Mementostate
getState ()setState ()
CareTaker
return new Memento (state) state=m.getState()
aCareTaker anOriginator aMemento
createMemento ()new Memento
setState ()
setMemento (aMemento) getState ()
MJ. Blin The design patterns
Memento (suite)
Exemple :
ElementGraphique
xDebutyDebutxFinyFincouleur
Memento
getState ()setState ()
Action
deplace (ElementGrahique,real, real)changeDimension (ElementGraphique, real, real, real, real)changeCouleur(ElementGraphique, Couleur)defaire (ElementGraphique)
Rectangle Cercle Ligne
setMemento (Memento)createMemento ():Mementodessine ()
xDebutyDebutxFinyFincouleur
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.
Originator CareTaker
MJ. Blin The design patterns
Memento (suite)
Javaclass 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
Observer
Quand un objet change d’état, tous ses dépendants en sont notifiés et sont mis à jour
Structure
Subject
attach (Observer)detach (Observer)notify ()
ConcreteSubject
getState ()setState ()
subjectState
Observerupdate ()
ConcreteObserver
update ()
observertState
1..*
observer
for all o in observero.update ()
return subjectState
subject
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
Observer(suite)
Exemple :
Résultats
attach (Presentation)notifyObservers ()
RésultatsDesVentes
attach (Presentation)notifyObservers()
Présentationnotify ()
ListeDeNombres
notify ()
1..*
observersubject
Histogramme
notify ()
Camembert
notify ()
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.
Subject Observer
ConcreteSubject
ConcreteObserver ConcreteObserver
ConcreteObserver
MJ. Blin The design patterns
Observer(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<observers.size();i++) { observers.elementAt(i).notify(s, this); } // fin du for } // fin de la methode notifyObservers
} // fin de la classe Resultats
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
Strategy
Définit une famille d’algorithmes et permet à une application d’utiliser l’un ou l’autre
algorithme indifféremment
Context
contextInterface ()
Strategy
algorithmInterface ()
ConcreteStrategyA
algorithmInterface ()
ConcreteStrategyB
algorithmInterface ()
strategy
strategy.algorihtmInterface ()
L’objet Context est lié à l’objet ConcreteStrategy correspondant à l’algorithme qui convient. L’opération contextInterface lance l’exécution de l’algorithme ainsi choisi.
MJ. Blin The design patterns
Strategy(suite)
Exemple :
AfficheCharges
afficheChargesEmp ()
ChargesEmp
calcul ()
ChargesEmpF
calcul ()
ChargesEmpGB
calcul ()
implantation
implantation.calcul ()
ChargesEmpI
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.
Context Strategy
ConcreteStategy ConcreteStategy ConcreteStategy
MJ. Blin The design patterns
Strategy(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
Visitor
Crée des classes qui traitent d'un ensemble d' instances de manière spécifique
VisitedClasse
accept ()
AbstractVisitor
visit ()
ConcreteVisitorA
visit ()
ConcreteVisitorB
visit ()
Visitor.visit ()
application VisitedInstance c:ConcreteVisitor
accept (c)visit (this)
MJ. Blin The design patterns
Visitor(suite)
Offre
OffreALEtranger
Visitor
VisitorOffre VisitorALEtranger
1..*
accept (VisitorALEtranger v)
visit (Offre o)
duree
visit (Offre o) visit (Offre o)visit (OffreALEtranger e)
accept (VisitorOffre v)
niveauEtudesRequis
MJ. Blin The design patterns
Visitor(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
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
Visitor(suite)
MJ. Blin The design patterns
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; i<offres.size();i++) {offres(i+1).accept(v);offres(i+1).accept(ve);
} // fin du for
System.out.println ("duree moyenne des offres =" , v.getDureeMoyenne);
System.out.println ("niveau moyen d'études requis pour les offres a l'etranger =" , ve.niveauMoyen);
} // fin du main
// fin de la classe Application
Visitor(fin)