162
Design Patterns (patrons de conception) GLO-3001 Architecture logicielle Luc Lamontagne Hiver2010

DesignPatterns comportement H10 - Université Lavallamontagne/glo3001/DesignPatterns...Patrons de comportement • Memento – Capturer et extraire l’état interne d’un objet •

  • Upload
    others

  • View
    9

  • Download
    0

Embed Size (px)

Citation preview

Page 1: DesignPatterns comportement H10 - Université Lavallamontagne/glo3001/DesignPatterns...Patrons de comportement • Memento – Capturer et extraire l’état interne d’un objet •

Design Patterns(patrons de conception)

GLO-3001 Architecture logicielle

Luc LamontagneHiver2010

Page 2: DesignPatterns comportement H10 - Université Lavallamontagne/glo3001/DesignPatterns...Patrons de comportement • Memento – Capturer et extraire l’état interne d’un objet •

Patrons de comportement

• Objectifs

– Assigner les responsabilités aux différents objets qui composent un système

– Décrire l'organisation des composantes et des – Décrire l'organisation des composantes et des mécanismes de communication entre les composantes

– Faciliter l'évolution du comportement des classes

– Maintenir un couplage faible

Friday, February 05, 2010 Luc Lamontagne 2

Page 3: DesignPatterns comportement H10 - Université Lavallamontagne/glo3001/DesignPatterns...Patrons de comportement • Memento – Capturer et extraire l’état interne d’un objet •

Patrons de comportement

• Chain of Responsibility

– Passer une requête à travers une chaîne d’objets candidats jusqu’à ce que l’un d’entre eux puisse traiter la requête

• Commande– Encapsuler une requête dans un objet

• Interpréteur•

– Définir pour un langage donné une représentation de sa grammaire et un interpréteur qui utilise cette représentation

• Itérateur– Fournir une manière d’accéder séquentiellement aux éléments d’une

collection d’objets

• Médiateur– Définir un objet qui encapsule les détails des communications entre

plusieurs objets

Friday, February 05, 2010 Luc Lamontagne 3

Page 4: DesignPatterns comportement H10 - Université Lavallamontagne/glo3001/DesignPatterns...Patrons de comportement • Memento – Capturer et extraire l’état interne d’un objet •

Patrons de comportement

• Memento

– Capturer et extraire l’état interne d’un objet

• Observateur– Notifier le changement d’état d’un objet à plusieurs autres objets

• State

– Permettre à un objet de modifier son comportement lorsque son état – Permettre à un objet de modifier son comportement lorsque son état change

• Stratégie– Définir une famille d’algorithmes interchangeables qui offrent la

même interface

• Template Method

– Définir le squelette d’un algorithme et laisser les sous-classes implanter les détails des étapes

Friday, February 05, 2010 Luc Lamontagne 4

Page 5: DesignPatterns comportement H10 - Université Lavallamontagne/glo3001/DesignPatterns...Patrons de comportement • Memento – Capturer et extraire l’état interne d’un objet •

Patrons de comportement

• Visiteur– Définir de nouvelles opérations sans modifier les classes des

éléments sur lesquelles les opérations agissent

• Null Object– Fournir un objet répondant à l’interface attendue par le client

mais n’offrant aucun comportementmais n’offrant aucun comportement

Friday, February 05, 2010 Luc Lamontagne 5

Page 6: DesignPatterns comportement H10 - Université Lavallamontagne/glo3001/DesignPatterns...Patrons de comportement • Memento – Capturer et extraire l’état interne d’un objet •

Itérateur

• Fournir une manière d’accéder séquentiellement aux éléments d’une collection d’objets

– sans révéler la représentation interne de la collection

• La collection peut contenir d’autres collections•

– Exemple: Texte � Groupe de Phrases � Groupe de Mots

• Itérateur

– Interface publique pour naviguer sur les éléments du contenants

– Déjà disponible en Java • Exemple : java.util.List ou java.sql.ResultSet

Friday, February 05, 2010 Luc Lamontagne 6

Page 7: DesignPatterns comportement H10 - Université Lavallamontagne/glo3001/DesignPatterns...Patrons de comportement • Memento – Capturer et extraire l’état interne d’un objet •

Itérateur

• Solution– Encapsuler les opérations de parcours d’une collection

• Interface (java.util.ListIterator)

– Créer une classe qui implante la logique nécessaire au parcours des éléments de la collection

– Créer une méthode de la collection qui permet d’obtenir un – Créer une méthode de la collection qui permet d’obtenir un Itérateur

– Itérateur externe• Une classe externe implante les opérations de parcours de la

collection – Itérateur spécifique à la collection

• Maintient une référence sur une copie de la collection• Possible d’avoir plus d’un Itérateur sur la collection au même moment

Friday, February 05, 2010 Luc Lamontagne 7

Page 8: DesignPatterns comportement H10 - Université Lavallamontagne/glo3001/DesignPatterns...Patrons de comportement • Memento – Capturer et extraire l’état interne d’un objet •

Itérateur externe

8

Page 9: DesignPatterns comportement H10 - Université Lavallamontagne/glo3001/DesignPatterns...Patrons de comportement • Memento – Capturer et extraire l’état interne d’un objet •

Itérateur interne

9

Page 10: DesignPatterns comportement H10 - Université Lavallamontagne/glo3001/DesignPatterns...Patrons de comportement • Memento – Capturer et extraire l’état interne d’un objet •

Itérateur interne vs. externe

Friday, February 05, 2010 Luc Lamontagne 10

a) Itérateur interne b) Itérateur filtreur externe

Page 11: DesignPatterns comportement H10 - Université Lavallamontagne/glo3001/DesignPatterns...Patrons de comportement • Memento – Capturer et extraire l’état interne d’un objet •

Itérateur

• Conséquences– Permet de parcourir les éléments d’une collection

de façon standardisée

– Permet d’encapsuler les détails du parcours de la structure d’une collectionstructure d’une collection

– Permet de supporter différents types de parcours• Ordre particulier

• Filtrage des éléments

– Permet d’obtenir plus d’un point d’accès sur une collection (External Iterator)

Friday, February 05, 2010 Luc Lamontagne 11

Page 12: DesignPatterns comportement H10 - Université Lavallamontagne/glo3001/DesignPatterns...Patrons de comportement • Memento – Capturer et extraire l’état interne d’un objet •

Itérateur - Exemple

• File avec priorité

– Les éléments de la file sont associés à un indice de priorité relatif

• Indice élevé � Haute priorité

12

• Indice faible � Basse priorité

Page 13: DesignPatterns comportement H10 - Université Lavallamontagne/glo3001/DesignPatterns...Patrons de comportement • Memento – Capturer et extraire l’état interne d’un objet •

Itérateur externe - Exemple

/**

* Itérateur de collection

*/

public interface IIterator {

public void first();

public void next();

public boolean hasNext();

public Object getCurrent();

}

13

/**

* Collection d'objets (IAggregate)

*/

public interface IAggregate {

public IIterator createIterator();

}

Page 14: DesignPatterns comportement H10 - Université Lavallamontagne/glo3001/DesignPatterns...Patrons de comportement • Memento – Capturer et extraire l’état interne d’un objet •

Itérateur externe - Exemple/**

* Queue avec priorité (ConcreteAggregate)

*/

public class PriorityQueue implements IAggregate {

private Vector<Object> queue;

private Vector<Integer> values;

public PriorityQueue() {

this.queue = new Vector<Object>();

this.values = new Vector<Integer>();

14

this.values = new Vector<Integer>();

}

public void add(Object o, int value) {

// ... //

}

public void remove(int i) {

// ... ///

}

// ...

Page 15: DesignPatterns comportement H10 - Université Lavallamontagne/glo3001/DesignPatterns...Patrons de comportement • Memento – Capturer et extraire l’état interne d’un objet •

Itérateur externe - Exemple

// ...

public Object get(int i) {

// ... //

}

public int size() {

return this.queue.size();

15

return this.queue.size();

}

public IIterator createIterator() {

return new PriorityQueueIterator(this);

}

}

Page 16: DesignPatterns comportement H10 - Université Lavallamontagne/glo3001/DesignPatterns...Patrons de comportement • Memento – Capturer et extraire l’état interne d’un objet •

Itérateur externe - Exemple

/**

* Iterateur pour une queue de priorité (ConcreteIterator)

*/

public class PriorityQueueIterator implements IIterator {

private PriorityQueue queue;

private int position;

public PriorityQueueIterator(PriorityQueue queue) {

16

this.queue = queue;

position = 0;

}

public void first() {

this.position = 0;

}

// ...

Page 17: DesignPatterns comportement H10 - Université Lavallamontagne/glo3001/DesignPatterns...Patrons de comportement • Memento – Capturer et extraire l’état interne d’un objet •

Itérateur externe - Exemple

// ...

public void next() {

this.position++;

if (this.position >= this.queue.size()) {

this.position = this.queue.size() - 1;

}

}

17

public boolean hasNext() {

return this.position < this.queue.size() - 1;

}

public Object getCurrent() {

return this.queue.get(this.position);

}

}

Page 18: DesignPatterns comportement H10 - Université Lavallamontagne/glo3001/DesignPatterns...Patrons de comportement • Memento – Capturer et extraire l’état interne d’un objet •

Itérateur externe - Exemple

public class Main {

public static void main(String[] args) {

PriorityQueue queue = new PriorityQueue();

queue.add("A", 1);

queue.add("D", 4);

queue.add("C", 3);

queue.add("G", 7);

queue.add("E", 5);

queue.add("F", 6);

queue.add("B", 2);

18

queue.add("B", 2);

queue.add("H", 8);

IIterator iter = queue.createIterator();

iter.first();

while (iter.hasNext()) {

System.out.println((String)iter.getCurrent());

iter.next();

}

System.out.println((String)iter.getCurrent());

}

}

Page 19: DesignPatterns comportement H10 - Université Lavallamontagne/glo3001/DesignPatterns...Patrons de comportement • Memento – Capturer et extraire l’état interne d’un objet •

Itérateur interne - Exemple

/**

* Queue avec priorité (ConcreteAggregate)

*/

public class PriorityQueue implements IAggregate, IIterator {

private Vector<Object> queue;

private Vector<Integer> values;

private int cursor;

public PriorityQueue() {

this.queue = new Vector<Object>();

19

this.queue = new Vector<Object>();

this.values = new Vector<Integer>();

this.cursor = 0;

}

public void add(Object o, int value) {

// ... //

}

// ...

Page 20: DesignPatterns comportement H10 - Université Lavallamontagne/glo3001/DesignPatterns...Patrons de comportement • Memento – Capturer et extraire l’état interne d’un objet •

Itérateur interne - Exemple

// ...

public void remove(int i) {// ... //

}

public Object get(int i) {// ... //

}

20

public int size() {return this.queue.size();

}

public void first() {this.cursor = 0;

}

// ...

Page 21: DesignPatterns comportement H10 - Université Lavallamontagne/glo3001/DesignPatterns...Patrons de comportement • Memento – Capturer et extraire l’état interne d’un objet •

Itérateur interne - Exemple

// ...

public void next() {

this.cursor++;

if (this.cursor >= size()) {

this.cursor = size() - 1;

}

}

21

public boolean hasNext() {

return this.cursor < size() - 1;

}

public Object getCurrent() {

return get(this.cursor);

}

}

Page 22: DesignPatterns comportement H10 - Université Lavallamontagne/glo3001/DesignPatterns...Patrons de comportement • Memento – Capturer et extraire l’état interne d’un objet •

Itérateur interne - Exemple

public class Main {

public static void main(String[] args) {

PriorityQueue queue = new PriorityQueue();

queue.add("A", 1);

queue.add("D", 4);

queue.add("C", 3);

queue.add("G", 7);

queue.add("E", 5);

queue.add("F", 6);

22

queue.add("F", 6);

queue.add("B", 2);

queue.add("H", 8);

queue.first();

while (queue.hasNext()) {

System.out.println((String)queue.getCurrent());

queue.next();

}

System.out.println((String)queue.getCurrent());

}

}

Page 23: DesignPatterns comportement H10 - Université Lavallamontagne/glo3001/DesignPatterns...Patrons de comportement • Memento – Capturer et extraire l’état interne d’un objet •

Chain of Responsibility

• Passer une requête à travers une chaîne d’objets candidats jusqu’à ce que l’un d’entre eux puisse traiter la requête

• Problème• Problème– Plusieurs objets peuvent possiblement répondre à une

requête– Le client n'est pas en mesure de choisir un répondant– On veut permettre aux répondants candidats de

répondre à la requête tout en conservant un couplage faible entre le client et les candidats

Friday, February 05, 2010 Luc Lamontagne 23

Page 24: DesignPatterns comportement H10 - Université Lavallamontagne/glo3001/DesignPatterns...Patrons de comportement • Memento – Capturer et extraire l’état interne d’un objet •

Chain of Responsibility

• Solution– Créer une chaîne de répondants (handlers)

• Les répondants implantent tous la même interface

– Chaque candidat maintient une référence sur le candidat suivant de la chaîne

– Chaque candidat maintient une référence sur le candidat suivant de la chaîne

– La requête est passée au premier candidat de la chaîne

• S'il peut répondre, la requête est traitée• S'il ne peut répondre, la requête est passée au candidat

suivant

Friday, February 05, 2010 Luc Lamontagne 24

Page 25: DesignPatterns comportement H10 - Université Lavallamontagne/glo3001/DesignPatterns...Patrons de comportement • Memento – Capturer et extraire l’état interne d’un objet •

Chain of Responsibility

25

Page 26: DesignPatterns comportement H10 - Université Lavallamontagne/glo3001/DesignPatterns...Patrons de comportement • Memento – Capturer et extraire l’état interne d’un objet •

Chain of Responsibility

$400K$25K

Friday, February 05, 2010 Luc Lamontagne 26

Interface commun

Aux objets qui peuvent

approuver une

demande d’achat Chaque objet a une limite

différente d’autorisaton

$100K $200K

Page 27: DesignPatterns comportement H10 - Université Lavallamontagne/glo3001/DesignPatterns...Patrons de comportement • Memento – Capturer et extraire l’état interne d’un objet •

Chain of Responsibility

Friday, February 05, 2010 Luc Lamontagne 27

Page 28: DesignPatterns comportement H10 - Université Lavallamontagne/glo3001/DesignPatterns...Patrons de comportement • Memento – Capturer et extraire l’état interne d’un objet •

Chain of Responsibility

• Pour obtenir une autorisation :

– Créer un ensemble– Arranger l’ensemble– Faire les connections

public abstract class PRHandler {private PRHandler nextHandler;private String handlerName;public PRHandler(String name) {

handlerName = name;}public String getName() {

Structure de

la chaîne

– Faire la requête– La demande en argument – Autorisation < limite– Si autoriser � fin– Si montant > limite_max

• Refus (message)

– Sinon au suivant !

public String getName() {return handlerName;

}public void setNextHandler(PRHandler handler) {

nextHandler = handler;};public abstract boolean authorize(PurchaseRequest

request);}public PRHandler getNextHandler() {

return nextHandler;}

Friday, February 05, 2010 Luc Lamontagne 28

Processus

d’autorisation

Page 29: DesignPatterns comportement H10 - Université Lavallamontagne/glo3001/DesignPatterns...Patrons de comportement • Memento – Capturer et extraire l’état interne d’un objet •

Chain of Responsibility

• Intention– Réduire le degré de couplage entre le client et les objets qui traite la

demande

• Si plusieurs objets peuvent faire un traitement :– On donne la chance à chacun en suivant un ordre séquentiel ;

– On forme une chaîne (référence vers le prochain objet) ;– On forme une chaîne (référence vers le prochain objet) ;

– Le premier objet décide s’il traite la requête ;

– Sinon il la passe au prochain objet ;

– La requête est passé d’un objet à l’autre :• Tant qu’elle n’est pas traitée; ou

• Tant que la fin de la chaîne n’est pas atteint.

Friday, February 05, 2010 Luc Lamontagne 29

Page 30: DesignPatterns comportement H10 - Université Lavallamontagne/glo3001/DesignPatterns...Patrons de comportement • Memento – Capturer et extraire l’état interne d’un objet •

Chain of Responsibility

• Conséquences– Permet de réduire le couplage entre le client et les répondants

• Le client ne connaît pas les répondants

– Permet plus de flexibilité dans la distribution des responsabilités• Les répondants peuvent être choisis à l’exécution

• Le choix des candidats modifie le comportement global du • Le choix des candidats modifie le comportement global du système

– Tous les objets de la chaîne ont la même interface. (favorise les changements)

– Les objets qui transmettent la requête n’ont pas à connaître les capacités de leurs successeurs

• Pas besoin de savoir quel objet va traiter la requête.

– Il n’y a aucune garantie de réponse à une requête

Friday, February 05, 2010 Luc Lamontagne 30

Page 31: DesignPatterns comportement H10 - Université Lavallamontagne/glo3001/DesignPatterns...Patrons de comportement • Memento – Capturer et extraire l’état interne d’un objet •

Chain of Responsibility- Exemple

• Système de classement de courriels

– À la réception d’un nouveau courriel, une série de filtre peuvent intercepter le courriel pour le classer dans un dossier particulierclasser dans un dossier particulier

– Si aucun filtre n’intercepte le courriel, il est placé dans la boîte de réception pour être classé manuellement

Friday, February 05, 2010 Luc Lamontagne 31

Page 32: DesignPatterns comportement H10 - Université Lavallamontagne/glo3001/DesignPatterns...Patrons de comportement • Memento – Capturer et extraire l’état interne d’un objet •

Chain of Responsibility - Exemple

/**

* Filtre pour les messages reçus (AbstractHandler)

*/

public abstract class AbstractFiltre {

private AbstractFiltre sucessor = null;

public AbstractFiltre(AbstractFiltre next) {

this.sucessor = next;

}

Successeur passé

au contructeur

32

public AbstractFiltre getNextHandler() {

return this.sucessor;

}

public abstract void request(String origine, String message);

}

Page 33: DesignPatterns comportement H10 - Université Lavallamontagne/glo3001/DesignPatterns...Patrons de comportement • Memento – Capturer et extraire l’état interne d’un objet •

Chain of Responsibility - Exemple

/**

* Filtre les messages s'il s'agit de spam (ConcreteHandler1)

*/

public class FiltreSpam extends AbstractFiltre {

public FiltreSpam(AbstractFiltre next) {

super(next);

33

}

public void request(String origine, String message) {

if (message.toLowerCase().contains("spam")) {

System.out.println("Ce message est un SPAM");

} else {

getNextHandler().request(origine, message);

}

}

}

Page 34: DesignPatterns comportement H10 - Université Lavallamontagne/glo3001/DesignPatterns...Patrons de comportement • Memento – Capturer et extraire l’état interne d’un objet •

Chain of Responsibility - Exemple

/**

* Filtre pour les messages provenant de l'université Laval (ConcreteHandler2)

*/

public class FiltreUlaval extends AbstractFiltre {

public FiltreUlaval(AbstractFiltre next) {

super(next);

34

super(next);

}

public void request(String origine, String message) {

if (origine.toLowerCase().contains("ulaval")) {

System.out.println("Ce message provient de l'Université Laval");

} else {

getNextHandler().request(origine, message);

}

}

}

Page 35: DesignPatterns comportement H10 - Université Lavallamontagne/glo3001/DesignPatterns...Patrons de comportement • Memento – Capturer et extraire l’état interne d’un objet •

Chain of Responsibility - Exemple

/**

* Dernier filtre qui effectue un traitement par défaut (ConcreteHandler3)

*/

public class FiltreAutre extends AbstractFiltre {

public FiltreAutre(AbstractFiltre next) {

35

public FiltreAutre(AbstractFiltre next) {

super(next);

}

public void request(String origine, String message) {

System.out.println("Message placé dans la boîte au lettre pour triage manuel");

}

}Fin de la chaîne

Page 36: DesignPatterns comportement H10 - Université Lavallamontagne/glo3001/DesignPatterns...Patrons de comportement • Memento – Capturer et extraire l’état interne d’un objet •

Chain of Responsibility - Exemple

public class Main {

public static void main(String[] args) {

AbstractFiltre chaine = new FiltreSpam(new FiltreUlaval(new FiltreAutre(null)));

chaine.request("[email protected]", "spam: ceci est un spam !!!");

chaine.request("[email protected]", "Message de l'Université Laval");

36

chaine.request("[email protected]", "Message de l'Université Laval");

chaine.request("[email protected]", "message non filtré");

}

}

Page 37: DesignPatterns comportement H10 - Université Lavallamontagne/glo3001/DesignPatterns...Patrons de comportement • Memento – Capturer et extraire l’état interne d’un objet •

Commande

• Encapsuler une requête dans un objet• Problème

– On veut encapsuler les demandes de service dans un objet

• Permet la manipulation des requêtes• Permet la manipulation des requêtes– Ordonnancement– Groupement– Exécution différée

– On veut configurer un objet en spécifiant les actions à effectuer sur le système lors de requêtes ou d’événements

– On veut permettre les retours en arrière (undo)

Friday, February 05, 2010 Luc Lamontagne 37

Page 38: DesignPatterns comportement H10 - Université Lavallamontagne/glo3001/DesignPatterns...Patrons de comportement • Memento – Capturer et extraire l’état interne d’un objet •

Commande

• Solution– Encapsuler les requêtes dans des classes (Command)

• Elles implantent tous la même interface

• Elles sont spécifiques aux objets du système sur lesquelles elles sont effectuées (Receivers)elles sont effectuées (Receivers)

– Une classe manipule et invoque les requêtes (Invoker)

– L’ajout de nouvelles fonctionnalités se fait par la définition de nouveaux types de requêtes• Pas de modification du système

Friday, February 05, 2010 Luc Lamontagne 38

Page 39: DesignPatterns comportement H10 - Université Lavallamontagne/glo3001/DesignPatterns...Patrons de comportement • Memento – Capturer et extraire l’état interne d’un objet •

Commande

39

Page 40: DesignPatterns comportement H10 - Université Lavallamontagne/glo3001/DesignPatterns...Patrons de comportement • Memento – Capturer et extraire l’état interne d’un objet •

Commande

• Séquence d’utilisation

1. Le client crée et configure un objet Command

– Définit les opérations que la Command exécute sur le Receiver

2. Le client passe la Command à l’Invoker

40

2. Le client passe la Command à l’Invoker

3. En temps voulu, l’Invoker lance l’exécution de la Command

4. La Command exécute ses opérations sur le Receiver

Page 41: DesignPatterns comportement H10 - Université Lavallamontagne/glo3001/DesignPatterns...Patrons de comportement • Memento – Capturer et extraire l’état interne d’un objet •

Command

41

Page 42: DesignPatterns comportement H10 - Université Lavallamontagne/glo3001/DesignPatterns...Patrons de comportement • Memento – Capturer et extraire l’état interne d’un objet •

Commande

• Particularité de ce design:

– Pas d’interaction direct Invoker – Receiver

– Nouvelle fonctionnalité � nouvelle commande• Pas de modification de code (open-closed principle)

– Objet de commande offre plusieurs possibilités– Objet de commande offre plusieurs possibilités• Stocker les commandes

• Reporter ou prioriser leur exécution

• Fonction Undo ()

• Exécution conjointe de plusieurs commandes

Friday, February 05, 2010 Luc Lamontagne 42

Page 43: DesignPatterns comportement H10 - Université Lavallamontagne/glo3001/DesignPatterns...Patrons de comportement • Memento – Capturer et extraire l’état interne d’un objet •

Command• Conséquences

– Découple l’objet qui demande les services de celui qui connaît les détails des opérations nécessaires à l’exécution

– Facilite l’ajout de nouvelles opérations

43

• Pas de modification du système

– Permet de manipuler les commandes

• Ordonnancement

• Groupement

• Exécution différée

• Retour en arrière (undo)

Page 44: DesignPatterns comportement H10 - Université Lavallamontagne/glo3001/DesignPatterns...Patrons de comportement • Memento – Capturer et extraire l’état interne d’un objet •

Commande

Friday, February 05, 2010 Luc Lamontagne 44

Page 45: DesignPatterns comportement H10 - Université Lavallamontagne/glo3001/DesignPatterns...Patrons de comportement • Memento – Capturer et extraire l’état interne d’un objet •

Commande

Mauvaise approche :

class ButtonHandler implements ActionListener {public void actionPerformed(ActionEvent e) {

if (e.getActionCommand().equals(FTPGUI.EXIT)) {System.exit(1);

}if (e.getActionCommand().equals(FTPGUI.UPLOAD)) {

int index = localList.getSelectedIndex();

Trop de vérifications

de conditions !

Tout dans la même classe.int index = localList.getSelectedIndex();String selectedItem = localList.getSelectedValue().toString();((DefaultListModel) localList.getModel()).remove(index);((DefaultListModel) remoteList.getModel()).addElement(selectedItem);

}

if (e.getActionCommand().equals(FTPGUI.DOWNLOAD)) {int index = remoteList.getSelectedIndex();String selectedItem = remoteList.getSelectedValue().toString();((DefaultListModel) remoteList.getModel()).remove(index);((DefaultListModel) localList.getModel()).addElement(selectedItem);

}if (e.getActionCommand().equals(FTPGUI.DELETE)) {

…}

Friday, February 05, 2010 Luc Lamontagne 45

Tout dans la même classe.

Page 46: DesignPatterns comportement H10 - Université Lavallamontagne/glo3001/DesignPatterns...Patrons de comportement • Memento – Capturer et extraire l’état interne d’un objet •

Commande

APPROCHE COMMANDE

interface CommandInterface {

public void processEvent();

}

class UploadButton extends JButton

implements CommandInterface {

class DownloadButton extends JButton

implements CommandInterface {

public void processEvent() {

int index = remoteList.getSelectedIndex();

String selectedItem = remoteList.getSelectedValue().toString();

((DefaultListModel) remoteList.getModel()).remove(index);

((DefaultListModel) localList.getModel()).addElement(

Les boutons

implémentent

les commandes

public void processEvent() {

int index = localList.getSelectedIndex();

String selectedItem = localList.getSelectedValue().toString();

((DefaultListModel) localList.getModel()).remove(index);

((DefaultListModel) remoteList.getModel()).addElement(selectedItem);

}

public UploadButton(String name) {

super(name);

}

}

((DefaultListModel) localList.getModel()).addElement(

selectedItem);

}

public DownloadButton(String name) {

super(name);

}

}

class buttonHandler implements ActionListener {

public void actionPerformed(ActionEvent e) {

CommandInterface CommandObj =

(CommandInterface) e.getSource();

CommandObj.processEvent();

}

}

Friday, February 05, 2010 Luc Lamontagne 46

Les événements sont

associés aux commandes

Page 47: DesignPatterns comportement H10 - Université Lavallamontagne/glo3001/DesignPatterns...Patrons de comportement • Memento – Capturer et extraire l’état interne d’un objet •

Commande - Exemple

• Calculatrice de base

– Commandes = Opérations mathématiques

• Addition

• Soustraction

47

• Multiplication

• Division

– Supporte les retours en arrière

Page 48: DesignPatterns comportement H10 - Université Lavallamontagne/glo3001/DesignPatterns...Patrons de comportement • Memento – Capturer et extraire l’état interne d’un objet •

Commande - Exemple

/**

* Calculateur basic (Receiver)

*/

public class Calculateur {

private double total;

public Calculateur() {

total = 0;

}

//...

public void multiplyBy(double valeur) {

this.total *= valeur;

}

}

public void add(double valeur) {

this.total += valeur;

}

public void substract(double valeur) {

this.total -= valeur;

}

//...

public void divideBy(double valeur) {

this.total /= valeur;

}

public double getTotal() {

return this.total;

}

}

48

Page 49: DesignPatterns comportement H10 - Université Lavallamontagne/glo3001/DesignPatterns...Patrons de comportement • Memento – Capturer et extraire l’état interne d’un objet •

Commande - Exemple

/**

* Commande (ICommand)

*/

public interface ICommand {

public void execute();

public void undo();

}

49

}

Page 50: DesignPatterns comportement H10 - Université Lavallamontagne/glo3001/DesignPatterns...Patrons de comportement • Memento – Capturer et extraire l’état interne d’un objet •

Commande - Exemple

/**

* Addition

*/

public class Addition implements ICommand {

private double valeur = 0;

private Calculateur calc;

public Addition(Calculateur calc, double valeur) {

this.calc = calc;

this.valeur = valeur;

50

this.valeur = valeur;

}

public void execute() {

this.calc.add(this.valeur);

}

public void undo() {

this.calc.substract(this.valeur);

}

}

Page 51: DesignPatterns comportement H10 - Université Lavallamontagne/glo3001/DesignPatterns...Patrons de comportement • Memento – Capturer et extraire l’état interne d’un objet •

Commande - Exemple

/**

* Multiplication

*/

public class Multiplication implements ICommand {

private double valeur = 0;

private Calculateur calc;

public Multiplication(Calculateur calc, double valeur) {

this.calc = calc;

51

this.valeur = valeur;

}

public void execute() {

this.calc.multiplyBy(this.valeur);

}

public void undo() {

this.calc.divideBy(this.valeur);

}

}

Page 52: DesignPatterns comportement H10 - Université Lavallamontagne/glo3001/DesignPatterns...Patrons de comportement • Memento – Capturer et extraire l’état interne d’un objet •

Commande - Exemple

/**

* Usager qui effectue les calculs (Invoker)

*/

public class Usager {

private ArrayList<ICommand> commands = new ArrayList<ICommand>();

private int current = -1;

public void storeCommand(ICommand cmd) { this.commands.add(cmd); }

public void executeCommand() {

52

public void executeCommand() {

ICommand cmd;

try {

cmd = this.commands.get(this.current + 1);

} catch (IndexOutOfBoundsException ex) {

cmd = null;

}

if (cmd != null) {

cmd.execute();

this.current++;

}

}

Page 53: DesignPatterns comportement H10 - Université Lavallamontagne/glo3001/DesignPatterns...Patrons de comportement • Memento – Capturer et extraire l’état interne d’un objet •

Commande - Exemple

// ...

public void undoCommand() {

ICommand cmd;

try {

cmd = this.commands.get(this.current);

} catch (IndexOutOfBoundsException ex) {

cmd = null;

53

}

if (cmd != null) {

cmd.undo();

this.current--;

}

}

}

// ...

Page 54: DesignPatterns comportement H10 - Université Lavallamontagne/glo3001/DesignPatterns...Patrons de comportement • Memento – Capturer et extraire l’état interne d’un objet •

Commande - Exemple

public class Main {

public static void main(String[] args) {

Calculateur calc = new Calculateur();

// 0 + 3 = 3

ICommand cmd1 = new Addition(calc, 3);

// 3 * 5 = 15

ICommand cmd2 = new Multiplication(calc, 5);

54

// 15 - 5 = 10

ICommand cmd3 = new Soustraction(calc, 5);

// 10 / 3 = 3.33

ICommand cmd4 = new Division(calc, 3);

Usager usager = new Usager();

usager.storeCommand(cmd1);

usager.storeCommand(cmd2);

usager.storeCommand(cmd3);

usager.storeCommand(cmd4);

// ...

Page 55: DesignPatterns comportement H10 - Université Lavallamontagne/glo3001/DesignPatterns...Patrons de comportement • Memento – Capturer et extraire l’état interne d’un objet •

Commande - Exemple

// ...

System.out.println(calc.getTotal());

usager.executeCommand(); // 0 + 3 = 3

System.out.println(calc.getTotal());

usager.executeCommand(); // 3 * 5 = 15

System.out.println(calc.getTotal());

usager.executeCommand(); // 15 - 5 = 10

System.out.println(calc.getTotal());

55

System.out.println(calc.getTotal());

usager.executeCommand(); // 10 / 3 = 3.33

System.out.println(calc.getTotal());

System.out.println("Annulation des 2 dernières opérations");

usager.undoCommand(); // 3.33 * 3 = 10

usager.undoCommand(); // 10 + 5 = 15

System.out.println(calc.getTotal());

}

}

Page 56: DesignPatterns comportement H10 - Université Lavallamontagne/glo3001/DesignPatterns...Patrons de comportement • Memento – Capturer et extraire l’état interne d’un objet •

Visiteur

• Définir de nouvelles opérations sans modifier les classes des éléments sur lesquelles les opérations agissent

• Problème– On veut définir une opération qui s’applique sur les éléments

d’une structure d’objets hétérogènesd’une structure d’objets hétérogènes– On veut regrouper les différentes versions de l’opération

(spécifiques à chaque type d’objet de la structure) dans une même classe

• Une opération donnée s’implante d’une manière différente sur chacune classes de la structure

– On veut ajouter des opérations sans modifier les classes de la structure

Friday, February 05, 2010 Luc Lamontagne 56

Page 57: DesignPatterns comportement H10 - Université Lavallamontagne/glo3001/DesignPatterns...Patrons de comportement • Memento – Capturer et extraire l’état interne d’un objet •

Visiteur

• Solution– Encapsuler l’opération dans une classe (Visitor)

• Séparer les implantations des données

– Définir une interface qui spécifie, pour chacune des – Définir une interface qui spécifie, pour chacune des classes, une méthode visit(param : type) qui prend en paramètre une référence sur un objet du type de la classe

– Le Visitor implante cette interface• Chaque méthode visit() implante une version spécifique de

l’opération représentée

• Ces méthodes font appel aux services des classes de la structure

Friday, February 05, 2010 Luc Lamontagne 57

Page 58: DesignPatterns comportement H10 - Université Lavallamontagne/glo3001/DesignPatterns...Patrons de comportement • Memento – Capturer et extraire l’état interne d’un objet •

Visiteur

• Solution (suite)– Définir une interface qui spécifie une méthode

accept(visitor) qui permet l’application d’une opération, représentée par un objet Visitor, d’être appliquée

– Les classes de la structure doivent implanter cette – Les classes de la structure doivent implanter cette interface

• Cette méthode fait appel à la méthode visit() du Visitor passé en paramètre qui est spécifique au type de la classe.

• Lors de cet appel à la méthode visit(), l’objet se passe lui-même en paramètre pour permettre au Visitor d’effectuer des requêtes sur cet objet

– Une opération = Un Visitor

Friday, February 05, 2010 Luc Lamontagne 58

Page 59: DesignPatterns comportement H10 - Université Lavallamontagne/glo3001/DesignPatterns...Patrons de comportement • Memento – Capturer et extraire l’état interne d’un objet •

Visitor

59

Page 60: DesignPatterns comportement H10 - Université Lavallamontagne/glo3001/DesignPatterns...Patrons de comportement • Memento – Capturer et extraire l’état interne d’un objet •

Visiteur

• Séquence d’utilisation1. La structure est créée2. Un objet Visitor, implantant une opération, est créé3. Pour appliquer l’opération à un objet de la structure,

on fait appel à la méthode accept() de l’objet en lui on fait appel à la méthode accept() de l’objet en lui passant le Visitor

4. Dans la méthode accept(), l’objet fait appel à la méthode visit() du Visitor qui est spécifique à son type

5. L’opération qu’implante le Visitor est alors lancée– Le Visitor fait appel aux méthodes de l’objet afin d’exécuter

l’opération

Friday, February 05, 2010 Luc Lamontagne 60

Page 61: DesignPatterns comportement H10 - Université Lavallamontagne/glo3001/DesignPatterns...Patrons de comportement • Memento – Capturer et extraire l’état interne d’un objet •

Visitor

61

Page 62: DesignPatterns comportement H10 - Université Lavallamontagne/glo3001/DesignPatterns...Patrons de comportement • Memento – Capturer et extraire l’état interne d’un objet •

Visiteur

• Conséquences– Facilite l’ajout de nouvelles opérations– Permet de regrouper les détails d’implantation d’une opération

applicable sur des objets hétérogènes– Permet de séparer une opération des données – Permet de parcourir des éléments hétérogènes d’une hiérarchie– Permet de parcourir des éléments hétérogènes d’une hiérarchie– Les Visitors peuvent accumuler des informations recueillies dans

différents objets visités– L’ajout de nouvelles classes sur lesquelles les opérations doivent

être effectuées est difficile• Demande de modifier tous les Visitors qui implantent l’interface

– Peut compromettre l’encapsulation d’une classe• Les objets doivent offrir une interface suffisante pour permettre aux

Visitors d’effectuer leurs opérations

Friday, February 05, 2010 Luc Lamontagne 62

Page 63: DesignPatterns comportement H10 - Université Lavallamontagne/glo3001/DesignPatterns...Patrons de comportement • Memento – Capturer et extraire l’état interne d’un objet •

Visiteur - Exemple

Friday, February 05, 2010 Luc Lamontagne 63

Page 64: DesignPatterns comportement H10 - Université Lavallamontagne/glo3001/DesignPatterns...Patrons de comportement • Memento – Capturer et extraire l’état interne d’un objet •

Visiteur - Exemple

Friday, February 05, 2010 Luc Lamontagne 64

Page 65: DesignPatterns comportement H10 - Université Lavallamontagne/glo3001/DesignPatterns...Patrons de comportement • Memento – Capturer et extraire l’état interne d’un objet •

Visiteur - Exemple

• Système de fichiers– On veut calculer la taille des éléments à partir

d’un élément du système de fichiers

– La taille des éléments• Fichier = Taille du fichier

• Dossier = Somme des tailles des éléments contenus

– Un Visitor parcours la hiérarchie à partir d’un nœud pour calculer la taille des éléments

Friday, February 05, 2010 Luc Lamontagne 65

Page 66: DesignPatterns comportement H10 - Université Lavallamontagne/glo3001/DesignPatterns...Patrons de comportement • Memento – Capturer et extraire l’état interne d’un objet •

Visiteur - Exemple

/**

* Visiteur (IVisitor)

*/

public interface IEntreeVisitor {

public void visit(Dossier d);

public void visit(Fichier f);

66

}

/**

* Élément visité (IElement)

*/

public interface IEntreeElement {

public void accept(IEntreeVisitor v);

}

Page 67: DesignPatterns comportement H10 - Université Lavallamontagne/glo3001/DesignPatterns...Patrons de comportement • Memento – Capturer et extraire l’état interne d’un objet •

Visiteur - Exemple/**

* Fichier (Leaf)

*/

public class Fichier implements IEntree, IEntreeElement {

private String nom;

private int taille;

public Fichier(String nom, int taille) {

this.nom = nom;

this.taille = taille;

}

67

public int getTaille() {

return this.taille;

}

public void print() {

System.out.println(" " + this.nom);

}

public void accept(IEntreeVisitor v) {

v.visit(this);

}

}

Page 68: DesignPatterns comportement H10 - Université Lavallamontagne/glo3001/DesignPatterns...Patrons de comportement • Memento – Capturer et extraire l’état interne d’un objet •

Visiteur - Exemple

/**

* Dossier (Composite)

*/

public class Dossier implements IEntree, IEntreeElement {

private String nom;

private Vector<IEntree> children;

public Dossier(String nom) {

this.nom = nom;

68

this.nom = nom;

this.children = new Vector<IEntree>();

}

public void add(IEntree e) {

this.children.add(e);

}

public void remove(IEntree e) {

this.children.remove(e);

}

// ...

Page 69: DesignPatterns comportement H10 - Université Lavallamontagne/glo3001/DesignPatterns...Patrons de comportement • Memento – Capturer et extraire l’état interne d’un objet •

Visiteur - Exemple

// ...

public IEntree get(int i) {

return this.children.get(i);

}

public int size() {

return this.children.size();

}

69

public void print() {

System.out.println("Dossier (" + this.nom + ")");

for (IEntree e : this.children) {

e.print();

}

}

public void accept(IEntreeVisitor v) {

v.visit(this);

}

}

Page 70: DesignPatterns comportement H10 - Université Lavallamontagne/glo3001/DesignPatterns...Patrons de comportement • Memento – Capturer et extraire l’état interne d’un objet •

Visitor - Exemple

/**

* Visite la hiérarchie et calcul la taille totale

* des éléments contenus par la racine choisie (ConcreteVisitor)

*/

public class TailleVisitor implements IEntreeVisitor {

private int taille;

public TailleVisitor() {

70

this.taille = 0;

}

public int getTaille() {

return this.taille;

}

// ...

Page 71: DesignPatterns comportement H10 - Université Lavallamontagne/glo3001/DesignPatterns...Patrons de comportement • Memento – Capturer et extraire l’état interne d’un objet •

Visitor - Exemple// ...

public void visit(Dossier d) {

// Visite les éléments contenus dans le dossier

IEntree entree;

IEntreeElement elem;

for (int i = 0; i < d.size(); i++) {

entree = d.get(i);

if (entree instanceof IEntreeElement) {

elem = (IEntreeElement)entree;

71

elem.accept(this);

}

}

}

public void visit(Fichier f) {

// Additionne la taille du fichier au total

this.taille += f.getTaille();

}

}

Page 72: DesignPatterns comportement H10 - Université Lavallamontagne/glo3001/DesignPatterns...Patrons de comportement • Memento – Capturer et extraire l’état interne d’un objet •

Visitor - Exemple

public class Main {

public static void main(String[] args) {Dossier d1 = new Dossier("Racine");d1.add(new Fichier("bonjour.txt", 100));d1.add(new Fichier("toto.txt", 55));d1.add(new Fichier("titi.txt", 85));

Dossier d2 = new Dossier("Doc");d2.add(new Fichier("guide.doc", 235));

72

d2.add(new Fichier("guide.doc", 235));

d1.add(d2);

Dossier d3 = new Dossier("Temp");d1.add(d3);

TailleVisitor visitor1 = new TailleVisitor();d1.accept(visitor1);

// 100 + 55 + 85 + 235 = 475System.out.println("Taille du dossier Racine = " + visitor1.getTaille());

// ...

Page 73: DesignPatterns comportement H10 - Université Lavallamontagne/glo3001/DesignPatterns...Patrons de comportement • Memento – Capturer et extraire l’état interne d’un objet •

Visitor - Exemple

// ...

TailleVisitor visitor2 = new TailleVisitor();

d2.accept(visitor2);

// 235System.out.println("Taille du dossier Doc = " + visitor2.getTaille());

TailleVisitor visitor3 = new TailleVisitor();

73

TailleVisitor visitor3 = new TailleVisitor();d3.accept(visitor3);

// 0

System.out.println("Taille du dossier Temp = " + visitor3.getTaille());}

}

Page 74: DesignPatterns comportement H10 - Université Lavallamontagne/glo3001/DesignPatterns...Patrons de comportement • Memento – Capturer et extraire l’état interne d’un objet •

Médiateur

• Application = communication entre plusieurs objets– Interaction direct (point à point) possible lorsque le nombre d’objets

est faible

• Si on augmente le nombre d’objets– Interactions directes difficiles à cause du nombre élevé d’objets– Interactions directes difficiles à cause du nombre élevé d’objets

– Labyrinthe de référence– Rend difficile la maintenance– Réutilisation limitée (forte dépendance)

• On veut permettre l’interaction entre les objets sans que chacun ne maintienne des références directes sur les autres objets

Friday, February 05, 2010 Luc Lamontagne 74

Page 75: DesignPatterns comportement H10 - Université Lavallamontagne/glo3001/DesignPatterns...Patrons de comportement • Memento – Capturer et extraire l’état interne d’un objet •

Médiateur

Friday, February 05, 2010 Luc Lamontagne 75

a) Sans médiateur

b) Avec médiateur

Page 76: DesignPatterns comportement H10 - Université Lavallamontagne/glo3001/DesignPatterns...Patrons de comportement • Memento – Capturer et extraire l’état interne d’un objet •

Médiateur

• Solution– Encapsuler les détails des communications entre les objets

(Collegues) dans une classe centrale (Mediator)

– Le Mediator contrôle les interactions entre les objets• S’occupe de transmettre les messages• S’occupe de transmettre les messages• Il implante une interface précise

– Permet de le remplacer par d’autre Mediators

– Les Collegues ont une seule référence • Sur le Mediator

– Les Collegues peuvent évoluer de façon indépendante

Friday, February 05, 2010 Luc Lamontagne 76

Page 77: DesignPatterns comportement H10 - Université Lavallamontagne/glo3001/DesignPatterns...Patrons de comportement • Memento – Capturer et extraire l’état interne d’un objet •

Médiateur

77

Page 78: DesignPatterns comportement H10 - Université Lavallamontagne/glo3001/DesignPatterns...Patrons de comportement • Memento – Capturer et extraire l’état interne d’un objet •

Médiateur

• Conséquences

– Élimine les références directes

– Simplifie les interactions entre les objets

– Permet d’abstraire comment les objets – Permet d’abstraire comment les objets communiquent entre eux

– Permet de centraliser le contrôle des interactions entre les objets

– Facilite l’évolution des relations entre les objets

– Facilite l’évolution et la réutilisation des objets

Friday, February 05, 2010 Luc Lamontagne 78

Page 79: DesignPatterns comportement H10 - Université Lavallamontagne/glo3001/DesignPatterns...Patrons de comportement • Memento – Capturer et extraire l’état interne d’un objet •

Médiateur

• Avantages:– Plus facile de modifier la nature des interrelations entre objets

• Modification du comportement du médiateur

• Accompli par surclassement avec fonctionnalités additionnelles

– En retirant les dépendences inter-objets de chacun des objets de l’application favorise la réutilisation.l’application favorise la réutilisation.

– Tests unitaires d’objets plus facile (moins de référence entre objets).

– La modification d’une classe n’affecte pas les autres classes• Faible couplage entre classes

Friday, February 05, 2010 Luc Lamontagne 79

Page 80: DesignPatterns comportement H10 - Université Lavallamontagne/glo3001/DesignPatterns...Patrons de comportement • Memento – Capturer et extraire l’état interne d’un objet •

Médiateur vs.façade

Médiateur

• Abstraction pour simplifier les communications

• Communications entre objetspar l’entremise du médiateur

Objets connaissent l’existence

Façade

• Abstraction pour simplifier l’interface de haut-niveau

• Communications avec le client par l’entremise de la façade

Objets ne connaissent pas • Objets connaissent l’existencedu médiateur

• Communication bi-directionnelles

• Modification d’un objet ne modifie pas les autres objets

• Modification possible par surclassement

• Objets ne connaissent pas l’existence de la façade

• Communications uni-directionnelles

• Modification d’un objet ne modifie pas le client

• Modification possible par surclassement

Friday, February 05, 2010 Luc Lamontagne 80

Page 81: DesignPatterns comportement H10 - Université Lavallamontagne/glo3001/DesignPatterns...Patrons de comportement • Memento – Capturer et extraire l’état interne d’un objet •

Mediateur - Exemple

• Application de Chat

– Chaque participant est représenté par un objet

– Il n’y a aucun lien directe entre les participants

81

– Il n’y a aucun lien directe entre les participants

– Les participants passent par le chambre de Chat

pour échanger des messages

– Les participants sont identifiés par un nom unique

Page 82: DesignPatterns comportement H10 - Université Lavallamontagne/glo3001/DesignPatterns...Patrons de comportement • Memento – Capturer et extraire l’état interne d’un objet •

Mediateur - Exemple

/**

* Mediator abstrait

*/

public abstract class AbstractMediator {

private HashMap<String, AbstractCollegue> collegues = new HashMap<String, AbstractCollegue>();

public void register(String id, AbstractCollegue collegue) {

if (!this.collegues.containsKey(id)) {

this.collegues.put(id, collegue);

82

this.collegues.put(id, collegue);

}

collegue.setMediator(this);

}

public void send(String id, Object msg) {

AbstractCollegue c = this.collegues.get(id);

if (c != null) {

c.receive(msg);

}

}

}

Page 83: DesignPatterns comportement H10 - Université Lavallamontagne/glo3001/DesignPatterns...Patrons de comportement • Memento – Capturer et extraire l’état interne d’un objet •

Mediateur - Exemple

/**

* Chambre de chat (ConcreteMediator)

*/

public class Chatroom extends AbstractMediator {

public Chatroom() {

}

83

public void send(String id, Object msg) {

System.out.println("Message pour : " + id);

super.send(id, msg);

}

}

Page 84: DesignPatterns comportement H10 - Université Lavallamontagne/glo3001/DesignPatterns...Patrons de comportement • Memento – Capturer et extraire l’état interne d’un objet •

Mediateur - Exemple

/**

* Participants abstraits

*/

public abstract class AbstractCollegue {

private AbstractMediator mediator;

public void setMediator(AbstractMediator mediator) {

this.mediator = mediator;

}

84

public void send(String id, Object msg) {

this.mediator.send(id, msg);

}

// Callback

public abstract void receive(Object msg);

}

Page 85: DesignPatterns comportement H10 - Université Lavallamontagne/glo3001/DesignPatterns...Patrons de comportement • Memento – Capturer et extraire l’état interne d’un objet •

Mediateur - Exemple

/*** Participant au chat*/public class Participant extends AbstractCollegue {

private String id;

public Participant(String id) {this.id = id;

}

85

public void send(String id, String msg) {System.out.println(this.id + " envoi : " + msg);super.send(id, msg);

}

public String getId() {return this.id;

}

/

public void receive(Object msg) {

System.out.println(this.id + " a reçu : " + (String)msg);

}

}

Page 86: DesignPatterns comportement H10 - Université Lavallamontagne/glo3001/DesignPatterns...Patrons de comportement • Memento – Capturer et extraire l’état interne d’un objet •

Mediateur - Exemple

public class Main {

public static void main(String[] args) {

Chatroom chatroom = new Chatroom();

Participant robert = new Participant("Robert");

chatroom.register(robert.getId(), robert);

Participant julie = new Participant("Julie");

86

Participant julie = new Participant("Julie");

chatroom.register(julie.getId(), julie);

Participant maya = new Participant("Maya");

chatroom.register(maya.getId(), maya);

robert.send("Julie", "Bonjour Julie!");

julie.send("Robert", "Bonjour Robert!");

robert.send("Maya", "Bonjour Maya!");

}

}

Page 87: DesignPatterns comportement H10 - Université Lavallamontagne/glo3001/DesignPatterns...Patrons de comportement • Memento – Capturer et extraire l’état interne d’un objet •

Memento

• Capturer et extraire l’état interne d’un objet

• Problème– L’état d’un objet est défini par la valeur de ses

attributsattributs– La modification des attributs entraîne un changement

d’état– On veut pouvoir sauvegarder l’état de l’objet pour

pouvoir le restaurer plus tard– On ne veut pas exposer la représentation interne de

l’objet

Friday, February 05, 2010 Luc Lamontagne 87

Page 88: DesignPatterns comportement H10 - Université Lavallamontagne/glo3001/DesignPatterns...Patrons de comportement • Memento – Capturer et extraire l’état interne d’un objet •

Memento

• Solution– Définir une classe qui conserve une copie des valeurs des attributs

(Memento)• Copie de l’état de l’objet d’origine (Originator)• Une méthode de l’Originator permet d’obtenir un objet Memento qui

représente l’état actuel de celui-ci• Le Memento est un conteneur de données• Le Memento est un conteneur de données

– Lecture seule

– Les copies des attributs conservés dans le Memento ne doivent être accessible que par l’Originator

• Utilisation d’une interface sans méthodes pour permettre aux autres objets de manipuler les Mementos sans avoir accès aux accesseurs

– Définir une classe qui conserve et organise les Mementos (Caretaker)

Friday, February 05, 2010 Luc Lamontagne 88

Page 89: DesignPatterns comportement H10 - Université Lavallamontagne/glo3001/DesignPatterns...Patrons de comportement • Memento – Capturer et extraire l’état interne d’un objet •

Memento

89

Page 90: DesignPatterns comportement H10 - Université Lavallamontagne/glo3001/DesignPatterns...Patrons de comportement • Memento – Capturer et extraire l’état interne d’un objet •

Memento

90

Page 91: DesignPatterns comportement H10 - Université Lavallamontagne/glo3001/DesignPatterns...Patrons de comportement • Memento – Capturer et extraire l’état interne d’un objet •

Memento

• Conséquences– Préserve le principe d’encapsulation

– Permet de décharger l’Originator de la gestion des versions précédentes de son état

– Peut devenir coûteux en terme de mémoire et de temps – Peut devenir coûteux en terme de mémoire et de temps de calcul si la quantité d’information est importante

– Difficile de préserver l’encapsulation de manière stricte

– Difficile d’appliquer une politique efficace de gestion des Mementos par le Caretaker

• Combien et quels Mementos conserver?

• Quand supprimer un Memento?

Friday, February 05, 2010 Luc Lamontagne 91

Page 92: DesignPatterns comportement H10 - Université Lavallamontagne/glo3001/DesignPatterns...Patrons de comportement • Memento – Capturer et extraire l’état interne d’un objet •

Memento

• Exemple de conversion de données

Identifiant du dernier

enregistrement de client

Friday, February 05, 2010 Luc Lamontagne 92

Restoration de l’état

Page 93: DesignPatterns comportement H10 - Université Lavallamontagne/glo3001/DesignPatterns...Patrons de comportement • Memento – Capturer et extraire l’état interne d’un objet •

Memento - Exemple

• Rapport de projet

– On veut conserver des sauvegardes de l’avancement d’un rapport

– On conserve

93

• Le corps du rapport (texte)

• La date de la dernière sauvegarde

• Le nom du dernier auteur

Page 94: DesignPatterns comportement H10 - Université Lavallamontagne/glo3001/DesignPatterns...Patrons de comportement • Memento – Capturer et extraire l’état interne d’un objet •

Memento - Exemple/**

* Rapport de projet (Originator)

*/

public class Rapport {

private String auteur;

private String corps;

private GregorianCalendar date;

public Rapport(String auteur) {

this.auteur = auteur;

this.corps = "";

this.date = new GregorianCalendar();

94

this.date = new GregorianCalendar();

}

public String getAuteur() { return this.auteur;

}

public void setAuteur(String auteur) {this.auteur = auteur;

}

public String getCorps() {return this.corps;

}

//...

Page 95: DesignPatterns comportement H10 - Université Lavallamontagne/glo3001/DesignPatterns...Patrons de comportement • Memento – Capturer et extraire l’état interne d’un objet •

Memento - Exemple

// ...

public void setCorps(String texte) {this.corps = texte;

}

public IMementoHandling createMemento() {

IMementoHandling m = new Memento(this.auteur, this.corps, this.date);

this.date = new GregorianCalendar();

95

this.date = new GregorianCalendar();

return m;

}

public void restore(IMementoHandling m) {

Memento previous = (Memento)m;

this.auteur = previous.getAuteur();

this.corps = previous.getCorps();

this.date = previous.getDate();

}

}

Page 96: DesignPatterns comportement H10 - Université Lavallamontagne/glo3001/DesignPatterns...Patrons de comportement • Memento – Capturer et extraire l’état interne d’un objet •

Memento - Exemple

/**

* Interface de manipulation des Mementos

* par le Caretaker

*/

public interface IMementoHandling {

}

96

Page 97: DesignPatterns comportement H10 - Université Lavallamontagne/glo3001/DesignPatterns...Patrons de comportement • Memento – Capturer et extraire l’état interne d’un objet •

Memento - Exemple/**

* Sauvegarde de l'état interne

*/

public class Memento implements IMementoHandling {

private final String auteur;

private final String corps;

private final GregorianCalendar date;

public Memento(String auteur, String corps, GregorianCalendar date) {

this.auteur = auteur;

this.corps = corps;

this.date = date;

97

this.date = date;

}

public String getAuteur() {

return this.auteur;

}

public String getCorps() {

return this.corps;

}

public GregorianCalendar getDate() {

return this.date;

}

}

Page 98: DesignPatterns comportement H10 - Université Lavallamontagne/glo3001/DesignPatterns...Patrons de comportement • Memento – Capturer et extraire l’état interne d’un objet •

Memento - Exemple/**

* Historique des sauvegardes (Caretaker)

*/

public class Historique {

private ArrayList<IMementoHandling> states;

public Historique() {

this.states = new ArrayList<IMementoHandling>();

}

98

public void add(IMementoHandling m) {

this.states.add(m);

}

public IMementoHandling getMemento(int i) {

if (i < this.states.size()) {

return this.states.get(i);

} else {

return null;

}

}

}

Page 99: DesignPatterns comportement H10 - Université Lavallamontagne/glo3001/DesignPatterns...Patrons de comportement • Memento – Capturer et extraire l’état interne d’un objet •

Memento - Exemplepublic class Main {

public static void main(String[] args) {

Rapport rpt = new Rapport("Roger Lagrange");

Historique hist = new Historique();

System.out.println(rpt.getAuteur() + " [" + rpt.getCorps() + "]");

rpt.setCorps("Bonjour le monde!");

hist.add(rpt.createMemento());

System.out.println(rpt.getAuteur() + " [" + rpt.getCorps() + "]");

99

System.out.println(rpt.getAuteur() + " [" + rpt.getCorps() + "]");

rpt.setAuteur("Samuel Champagne");

rpt.setCorps("Bonjour à tout le monde!");

hist.add(rpt.createMemento());

System.out.println(rpt.getAuteur() + " [" + rpt.getCorps() + "]");

System.out.println("--- Retour à la première sauvegarde ---");

rpt.restore(hist.getMemento(0));

System.out.println(rpt.getAuteur() + " [" + rpt.getCorps() + "]");

}

}

Page 100: DesignPatterns comportement H10 - Université Lavallamontagne/glo3001/DesignPatterns...Patrons de comportement • Memento – Capturer et extraire l’état interne d’un objet •

Observateur

• Notifier le changement d’état d’un objet à plusieurs autres objets

• Problème• Problème

– Plusieurs composantes sont dépendantes de l’état d’un objet

– Lorsque l’état de l’objet change, les objets dépendants doivent en être notifiés

Friday, February 05, 2010 Luc Lamontagne 100

Page 101: DesignPatterns comportement H10 - Université Lavallamontagne/glo3001/DesignPatterns...Patrons de comportement • Memento – Capturer et extraire l’état interne d’un objet •

Observateur - Exemple

• Rapports de vente par département

Friday, February 05, 2010 Luc Lamontagne 101

Page 102: DesignPatterns comportement H10 - Université Lavallamontagne/glo3001/DesignPatterns...Patrons de comportement • Memento – Capturer et extraire l’état interne d’un objet •

Observateur

• Observateurs:– Un objet portant un intérêt à l’état du sujet– Doit savoir quand le sujet change d’état

• Sujet (subject): – Peut avoir plusieurs observateurs. – Construction dynamique d’une liste d’observateur par enregistrement.– Lorsqu’un changement survient, il avise les observateurs enregistrés.– Lorsqu’un changement survient, il avise les observateurs enregistrés.– Sur réception, les observateurs se synchronise avec l’état du sujet (mise à jour

de leurs attributs).– Donc le sujet est un publisher car il envoie des messages à tous les

souscripteurs (observers).– Les observateurs peuvent se désenregistrer.

Friday, February 05, 2010 Luc Lamontagne 102

Page 103: DesignPatterns comportement H10 - Université Lavallamontagne/glo3001/DesignPatterns...Patrons de comportement • Memento – Capturer et extraire l’état interne d’un objet •

Observateur

• Solution– Mettre en place un système de communication entre les objets

dépendants (Observers) et l’objet dont ils dépendent (Subject)

– Le sujet maintient une liste d’objets dépendants• Offre des services d’enregistrement et de désenregistrement• Offre des services d’enregistrement et de désenregistrement

– Les observateurs s’enregistrent auprès du sujet

– Les observateurs implantent une interface commune• Spécifie une méthode de notification (Callback)

– Lorsque l’état du sujet change, le sujet appelle la méthode de notification sur chacun des observateurs enregistrés

Friday, February 05, 2010 Luc Lamontagne 103

Page 104: DesignPatterns comportement H10 - Université Lavallamontagne/glo3001/DesignPatterns...Patrons de comportement • Memento – Capturer et extraire l’état interne d’un objet •

Observateur

• Modèle Pull– L’observateur maintient une référence sur le sujet– Le sujet offre une interface suffisante pour que les

observateurs puissent accéder aux attributs définissant son état

– Suite à une notification, l’observateur effectue des requêtes sur le sujet afin d’extraire son nouvel état

• Modèle Push– Lors d’une notification, le sujet envoi son nouvel état

aux observateurs• Paramètre de la méthode de notification (Callback)

Friday, February 05, 2010 Luc Lamontagne 104

Page 105: DesignPatterns comportement H10 - Université Lavallamontagne/glo3001/DesignPatterns...Patrons de comportement • Memento – Capturer et extraire l’état interne d’un objet •

Observateur - Pull

105

Page 106: DesignPatterns comportement H10 - Université Lavallamontagne/glo3001/DesignPatterns...Patrons de comportement • Memento – Capturer et extraire l’état interne d’un objet •

Observateur - Push

106

Page 107: DesignPatterns comportement H10 - Université Lavallamontagne/glo3001/DesignPatterns...Patrons de comportement • Memento – Capturer et extraire l’état interne d’un objet •

Observateur

• Conséquences– Permet d’assurer la consistance entre les états d’objets

dépendants– Permet d’assouplir le couplage entre le sujet et les observateurs

• Le sujet n’est pas lié aux observateurs

– Permet de notifier un changement à plusieurs classes – Permet de notifier un changement à plusieurs classes intéressées

– Permet de supporter la communication par diffusion (Broadcast)

– Peut entraîner des mises à jour en cascade– Si aucune stratégie ne permet de cibler ce qui a changé dans

l’état du sujet, les synchronisations des états des observateurs avec le sujet peut devenir très coûteuse

Friday, February 05, 2010 Luc Lamontagne 107

Page 108: DesignPatterns comportement H10 - Université Lavallamontagne/glo3001/DesignPatterns...Patrons de comportement • Memento – Capturer et extraire l’état interne d’un objet •

Observateur - Exemple

• Système de surveillance météorologique

– Des appareils prennent des mesures sur le terrain

• Thermomètre

• Baromètre

108

• …

– Des moniteurs enregistrent ou affiche les valeurs des mesures effectuées par les appareils

• Écran

• Journal des événements

Page 109: DesignPatterns comportement H10 - Université Lavallamontagne/glo3001/DesignPatterns...Patrons de comportement • Memento – Capturer et extraire l’état interne d’un objet •

Observateur (Pull) - Exemple

/**

* Observer object (IObserver)

*/

public interface IObserver {

public void update();

}

109

Page 110: DesignPatterns comportement H10 - Université Lavallamontagne/glo3001/DesignPatterns...Patrons de comportement • Memento – Capturer et extraire l’état interne d’un objet •

Observateur (Pull) - Exemple/**

* Abstract Subject (AbstractSubject)

*/

public class AbstractSubject {

private ArrayList<IObserver> observers;

public AbstractSubject() {

this.observers = new ArrayList<IObserver>();

}

110

public void register(IObserver o) {

this.observers.add(o);

}

public void unregister(IObserver o) {

this.observers.remove(o);

}

public void notifyObservers() {

for (IObserver o : this.observers) {

o.update();

}

}

}

Page 111: DesignPatterns comportement H10 - Université Lavallamontagne/glo3001/DesignPatterns...Patrons de comportement • Memento – Capturer et extraire l’état interne d’un objet •

Observateur (Pull) - Exemple/**

* Thermomètre qui donne la température d'une composante (ConcreteSubject)

*/

public class Thermometre extends AbstractSubject {

private double temperature;

public Thermometre(double temperature) {

this.temperature = temperature;

}

111

public double getTemperature() {

return this.temperature;

}

public void setTemperature(double t) {

this.temperature = t;

super.notifyObservers();

}

}

Page 112: DesignPatterns comportement H10 - Université Lavallamontagne/glo3001/DesignPatterns...Patrons de comportement • Memento – Capturer et extraire l’état interne d’un objet •

Observateur (Pull) - Exemple

/**

* Console de surveillance (ConcreteObserver)

*/

public class Console implements IObserver {

private Thermometre thermometre;

public Console(Thermometre t) {

this.thermometre = t;

112

this.thermometre = t;

}

public void update() {

double t = this.thermometre.getTemperature();

System.out.println("Console : Température actuelle = " + t);

}

}

Page 113: DesignPatterns comportement H10 - Université Lavallamontagne/glo3001/DesignPatterns...Patrons de comportement • Memento – Capturer et extraire l’état interne d’un objet •

Observateur (Pull) - Exemple

public class Main {

public static void main(String[] args) {

Thermometre thermometre = new Thermometre(0);

Console console = new Console(thermometre);

thermometre.register(console);

113

Journal journal = new Journal(thermometre);

thermometre.register(journal);

thermometre.setTemperature(5);

thermometre.setTemperature(7);

}

}

Page 114: DesignPatterns comportement H10 - Université Lavallamontagne/glo3001/DesignPatterns...Patrons de comportement • Memento – Capturer et extraire l’état interne d’un objet •

Observateur (Push) - Exemple

/**

* Observer object (IObserver)

*/

public interface IObserver {

public void update(Object state);

}

114

Page 115: DesignPatterns comportement H10 - Université Lavallamontagne/glo3001/DesignPatterns...Patrons de comportement • Memento – Capturer et extraire l’état interne d’un objet •

Observateur (Push) - Exemple/**

* Abstract Subject (AbstractSubject)

*/

public class AbstractSubject {

private ArrayList<IObserver> observers;

public AbstractSubject() {

this.observers = new ArrayList<IObserver>();

}

115

public void register(IObserver o) {

this.observers.add(o);

}

public void unregister(IObserver o) {

this.observers.remove(o);

}

public void notifyObservers(Object state) {

for (IObserver o : this.observers) {

o.update(state);

}

}

Page 116: DesignPatterns comportement H10 - Université Lavallamontagne/glo3001/DesignPatterns...Patrons de comportement • Memento – Capturer et extraire l’état interne d’un objet •

Observateur (Push) - Exemple

/**

* Thermomètre qui donne la température d'une composante (ConcreteSubject)

*/

public class Thermometre extends AbstractSubject {

private double temperature;

public Thermometre(double temperature) {

this.temperature = temperature;

116

}

public double getTemperature() {

return this.temperature;

}

public void setTemperature(double t) {

this.temperature = t;

super.notifyObservers(getTemperature());

}

}

Page 117: DesignPatterns comportement H10 - Université Lavallamontagne/glo3001/DesignPatterns...Patrons de comportement • Memento – Capturer et extraire l’état interne d’un objet •

Observateur (Push) - Exemple

/**

* Console de surveillance (ConcreteObserver)

*/

public class Console implements IObserver {

private Thermometre thermometre;

public Console(Thermometre t) {

this.thermometre = t;

}

117

public void update(Object state) {

Double t = (Double)state;

System.out.println("Console : Température actuelle = " + t);

}

}

Page 118: DesignPatterns comportement H10 - Université Lavallamontagne/glo3001/DesignPatterns...Patrons de comportement • Memento – Capturer et extraire l’état interne d’un objet •

Observateur (Push) - Exemple

public class Main {

public static void main(String[] args) {

Thermometre thermometre = new Thermometre(0);

Console console = new Console(thermometre);

thermometre.register(console);

Journal journal = new Journal(thermometre);

118

Journal journal = new Journal(thermometre);

thermometre.register(journal);

thermometre.setTemperature(5);

thermometre.setTemperature(7);

}

}

Page 119: DesignPatterns comportement H10 - Université Lavallamontagne/glo3001/DesignPatterns...Patrons de comportement • Memento – Capturer et extraire l’état interne d’un objet •

État (state)

• Permettre à un objet de modifier son comportement lorsque son état change

• Problème– L’état d’un objet est défini par la valeur des ses attributs– Une modification des attributs d’un objet amène un – Une modification des attributs d’un objet amène un

changement d’état– Le comportement d’un objet peut être influencé par son état

• Un objet implante donc différentes variantes de son comportement• Comportement choisi par des expressions conditionnelles

– On veut pouvoir changer le comportement d’un objet lorsque son état change

Friday, February 05, 2010 Luc Lamontagne 119

Page 120: DesignPatterns comportement H10 - Université Lavallamontagne/glo3001/DesignPatterns...Patrons de comportement • Memento – Capturer et extraire l’état interne d’un objet •

État (state)

• Exemple: un compte de banque dont les états sont :

– Sans frais de transaction: montant > seuil

– Avec frais de transaction : 0 < montant < seuil

– Débiteur : montant < 0– Débiteur : montant < 0

• Une transaction qui excède la limite est refusée

Friday, February 05, 2010 Luc Lamontagne 120

Page 121: DesignPatterns comportement H10 - Université Lavallamontagne/glo3001/DesignPatterns...Patrons de comportement • Memento – Capturer et extraire l’état interne d’un objet •

État (state)public class BusinessAccount {

public static final double MIN_BALANCE = 2000.00; public static final double OVERDRAW_LIMIT = -1000.00;private State objState;private String accountNumber;private double balance;

public void setState(State newState) { objState = newState; }public State getState() { return objState; }

public boolean deposit(double amount) {public boolean deposit(double amount) {return getState().deposit(amount);

}

public boolean withdraw(double amount) {return getState().withdraw(amount);

}

public BusinessAccount(String accountNum) {accountNumber = accountNum;objState = State.InitialState(this);

}public double getBalance() { return balance; }public void setBalance(double newBalance) {balance = newBalance;}

}

Friday, February 05, 2010 Luc Lamontagne 121

Page 122: DesignPatterns comportement H10 - Université Lavallamontagne/glo3001/DesignPatterns...Patrons de comportement • Memento – Capturer et extraire l’état interne d’un objet •

État (state)public class State {

private BusinessAccount context;

public BusinessAccount getContext() { return context; }

public void setContext(BusinessAccount newAccount) {context = newAccount;

} public State transitionState() { return null; }

public State(BusinessAccount account) { setContext(account); }

public static State InitialState(BusinessAccount account) {public static State InitialState(BusinessAccount account) {return new NoTransactionFeeState(account);

}

public boolean deposit(double amount) {double balance = getContext().getBalance();getContext().setBalance(balance + amount);transitionState();return true;

}

public boolean withdraw(double amount) {double balance = getContext().getBalance();getContext().setBalance(balance - amount);transitionState();return true;

}}Friday, February 05, 2010 Luc Lamontagne 122

Page 123: DesignPatterns comportement H10 - Université Lavallamontagne/glo3001/DesignPatterns...Patrons de comportement • Memento – Capturer et extraire l’état interne d’un objet •

État (state)

• Solution– Encapsuler les différents comportements que peut

prendre un objet en fonction de son état dans des classes distinctes (State)

• Les classes State implantent toutes la même interface• Les classes State implantent toutes la même interface

– Une Abstract Parent Class spécifie les méthodes de service qui sont influencées par l’état de l’objet

– La classe parent implante les méthodes de service de l’objet qui ne sont pas influencées

Friday, February 05, 2010 Luc Lamontagne 123

Page 124: DesignPatterns comportement H10 - Université Lavallamontagne/glo3001/DesignPatterns...Patrons de comportement • Memento – Capturer et extraire l’état interne d’un objet •

État (state)

• Solution (suite)– Des sous-classes implantent les méthodes abstraites qui

définissent le comportement de l’objet dans un état précis• Une sous-classe = Un état précis de l’objet

– Les requêtes sur les méthodes sensibles à l’état de l’objet sont redirigées vers la sous-classe qui représente l’état courant de l’objet

– Suite à une requête, l’état de l’objet est réévalué et une autre sous-classe est choisie pour représenter l’état courant

Friday, February 05, 2010 Luc Lamontagne 124

Page 125: DesignPatterns comportement H10 - Université Lavallamontagne/glo3001/DesignPatterns...Patrons de comportement • Memento – Capturer et extraire l’état interne d’un objet •

État (state)

125

Page 126: DesignPatterns comportement H10 - Université Lavallamontagne/glo3001/DesignPatterns...Patrons de comportement • Memento – Capturer et extraire l’état interne d’un objet •

État (state)

• Conséquences– Permet de regrouper les comportements en fonction du

contexte dans lequel le comportement est applicable– Facilite l’évolution et l’extension du comportement de l’objet– Élimine de nombreuses et complexes opérations conditionnelles– Permet de structurer le comportement d’un objet– Permet de structurer le comportement d’un objet– Rend explicite les changements d’état– Permet de partager des comportements entre plusieurs

instances d’une classe– La décentralisation de la logique des transitions d’état amène

des dépendances entre les objets State

– Augmente le nombre d’objets du système

Friday, February 05, 2010 Luc Lamontagne 126

Page 127: DesignPatterns comportement H10 - Université Lavallamontagne/glo3001/DesignPatterns...Patrons de comportement • Memento – Capturer et extraire l’état interne d’un objet •

État- Exemple

• Système de gestion d’un barrage hydroélectrique– Le barrage doit maintenir un certain niveau d’eau

– Pour contrôler le niveau d’eau, on peut• Ouvrir les valves

• Fermer les valves• Fermer les valves

– Lorsque les valves sont fermées, une accumulation naturelle s’effectue

– 3 états• Niveau bas � Fermer les valves

• Niveau normal � Ne rien faire

• Niveau élevé � Ouvrir les valves

Friday, February 05, 2010 Luc Lamontagne 127

Page 128: DesignPatterns comportement H10 - Université Lavallamontagne/glo3001/DesignPatterns...Patrons de comportement • Memento – Capturer et extraire l’état interne d’un objet •

État - Exemple/**

* Barrage hydroélectrique (Context)

*/

public class Barrage {

private AbstractState state;

private double quantite;

public Barrage() {

this.quantite = 0;

this.state = null;

128

}

public AbstractState getState() {

return this.state;

}

public void setState(AbstractState state) {

this.state = state;

}

// ...

Page 129: DesignPatterns comportement H10 - Université Lavallamontagne/glo3001/DesignPatterns...Patrons de comportement • Memento – Capturer et extraire l’état interne d’un objet •

État- Exemple// ...

public double getQuantite() {

return this.quantite;}

public void setQuantite(double qte) {

this.quantite = qte;}

public void ecouler(double qte) {

129

public void ecouler(double qte) {setQuantite(getQuantite() - qte);

}

public void accumuler(double qte) {setQuantite(getQuantite() + qte);

}

// service()public void ajusterNiveau() {

getState().ajusterNiveau();}

}

Page 130: DesignPatterns comportement H10 - Université Lavallamontagne/glo3001/DesignPatterns...Patrons de comportement • Memento – Capturer et extraire l’état interne d’un objet •

État- Exemple/**

* Abstract State

*/

public abstract class AbstractState {

public static final double MIN = 100;

public static final double MAX = 200;

private Barrage barrage;

public AbstractState(Barrage barrage) {

this.barrage = barrage;

130

this.barrage = barrage;

}

public Barrage getBarrage() {

return this.barrage;

}

public abstract void changeState(); // handle()

public abstract void ajusterNiveau(); // changeState()

}

Page 131: DesignPatterns comportement H10 - Université Lavallamontagne/glo3001/DesignPatterns...Patrons de comportement • Memento – Capturer et extraire l’état interne d’un objet •

État- Exemple/**

* Niveau d'eau normal dans le barrage (ConcreteState)

*/

public class NiveauNormal extends AbstractState {

public NiveauNormal(Barrage barrage) {

super(barrage);

}

// changeState

public void changeState() {

if (getBarrage().getQuantite() > MAX) {

131

if (getBarrage().getQuantite() > MAX) {

getBarrage().setState(new NiveauEleve(getBarrage()));

} else if (getBarrage().getQuantite() < MIN) {

getBarrage().setState(new NiveauBas(getBarrage()));

}

}

// handle

public void ajusterNiveau() {

System.out.println("Niveau normal : " + getBarrage().getQuantite());

getBarrage().accumuler(35); // accumulation naturelle

changeState();

}

}

Page 132: DesignPatterns comportement H10 - Université Lavallamontagne/glo3001/DesignPatterns...Patrons de comportement • Memento – Capturer et extraire l’état interne d’un objet •

État- Exemple/**

* Niveau d'eau élevé dans le barrage (ConcreteState)

*/

public class NiveauEleve extends AbstractState {

public NiveauEleve(Barrage barrage) {

super(barrage);

}

// changeState

public void changeState() {

if (getBarrage().getQuantite() < MIN) {

132

if (getBarrage().getQuantite() < MIN) {

getBarrage().setState(new NiveauBas(getBarrage()));

} else if (getBarrage().getQuantite() < MAX) {

getBarrage().setState(new NiveauNormal(getBarrage()));

}

}

// handle

public void ajusterNiveau() {

System.out.println("Niveau élevé : " + getBarrage().getQuantite());

getBarrage().ecouler(100); // Ouvrir les valves

changeState();

}

}

Page 133: DesignPatterns comportement H10 - Université Lavallamontagne/glo3001/DesignPatterns...Patrons de comportement • Memento – Capturer et extraire l’état interne d’un objet •

Stratégie

• Situation:– Plusieurs algorithmes applicables à un même problème

– On veut pouvoir choisir dynamiquement l’algorithme à utiliser selon les besoins actuels

• Approche • Approche – Définir une famille d’algorithmes interchangeables qui offrent

la même interface

– Chaque algorithme implanté dans une classe séparée (une stratégie)

– Les algorithmes offrent le même interface

– Séparation de l’implantation de l’algorithme et de son contexte d’utilisation

Friday, February 05, 2010 Luc Lamontagne 133

Page 134: DesignPatterns comportement H10 - Université Lavallamontagne/glo3001/DesignPatterns...Patrons de comportement • Memento – Capturer et extraire l’état interne d’un objet •

Stratégie

• Solution– Encapsuler les algorithmes dans des classes distinctes (Strategy)

• Les Strategy implantent toutes la même interface• Même service mais en utilisant des approches différentes

– L’objet client choisit l’algorithme à utiliser– L’objet client choisit l’algorithme à utiliser

– Le client doit fournir à l’algorithmes toutes les informations nécessaires ou offrir une interface suffisante pour que l’algorithme soit en mesure d’extraire lui-même les informations nécessaires

– L’algorithme est séparé de son contexte

Friday, February 05, 2010 Luc Lamontagne 134

Page 135: DesignPatterns comportement H10 - Université Lavallamontagne/glo3001/DesignPatterns...Patrons de comportement • Memento – Capturer et extraire l’état interne d’un objet •

Stratégie

135

Page 136: DesignPatterns comportement H10 - Université Lavallamontagne/glo3001/DesignPatterns...Patrons de comportement • Memento – Capturer et extraire l’état interne d’un objet •

Stratégie

• Conséquences– Permet de créer des familles d’algorithmes fournissant un

service commun– Offre une alternative à l’héritage pour supporter différents

algorithmes– Facilite l’évolution et l’ajout d’algorithmes– Facilite l’évolution et l’ajout d’algorithmes– Permet de choisir l’algorithme à l’exécution– Élimine de nombreuses opérations conditionnelles– Permet d’offrir différentes implantations d’un même

comportement– Le client doit connaître les algorithmes disponibles ainsi que la

logique permettant de sélectionner le bon algorithme– Augmente le nombre d’objets du système

Friday, February 05, 2010 Luc Lamontagne 136

Page 137: DesignPatterns comportement H10 - Université Lavallamontagne/glo3001/DesignPatterns...Patrons de comportement • Memento – Capturer et extraire l’état interne d’un objet •

Stratégie

• Avantages– Évite les séquences de conditions (open-closed principle)

– Plus simple et facile d’ajouter, d’enlever ou modifier un algorithme

– Éviter de dériver des classes qui comportent le contexte et – Éviter de dériver des classes qui comportent le contexte et l’algorithme

• Évite de faire une assocation statique entre un algorithme et un contexte

• Facilite le changement du comportement d’un contexte

• Évite les explosions combinatoires de sous-classes

Friday, February 05, 2010 Luc Lamontagne 137

Page 138: DesignPatterns comportement H10 - Université Lavallamontagne/glo3001/DesignPatterns...Patrons de comportement • Memento – Capturer et extraire l’état interne d’un objet •

Stratégie vs. State

• Choix:

– State : dépend de l’état du context objet

– Stratégie : dépend des besoins de l’application

• Context object:• Context object:

– State : peut changer d’état, les transitions sont bien définies par les caractéristiques d’une application

– Stratégie : ne change pas d’état.

Friday, February 05, 2010 Luc Lamontagne 138

Page 139: DesignPatterns comportement H10 - Université Lavallamontagne/glo3001/DesignPatterns...Patrons de comportement • Memento – Capturer et extraire l’état interne d’un objet •

Stratégie - Exemple

• Système permettant le cryptage de messages– Plusieurs algorithmes de cryptage

– Le client peut choisir l’algorithme à utiliser

Décalage (shift) d’un

caractère

Substitution de caractères à

partir d’une table de

139

caractère

Ex: hello � elloh

partir d’une table de

correspondance

Ex: hello � WXCCB

Substitution de mots à partir

d’une table

Ex: hello � toto

Rotation d’un caractère

Ex: hello � ifmmp

Context object

Page 140: DesignPatterns comportement H10 - Université Lavallamontagne/glo3001/DesignPatterns...Patrons de comportement • Memento – Capturer et extraire l’état interne d’un objet •

Stratégie - Exemple

/**

* Interface des stratégies (IStrategy)

*/

public interface IStrategy {

public String encrypter(String message);

public String decrypter(String message);

}

140

Page 141: DesignPatterns comportement H10 - Université Lavallamontagne/glo3001/DesignPatterns...Patrons de comportement • Memento – Capturer et extraire l’état interne d’un objet •

Stratégie - Exemple/**

* Rotation-Substitution (ConcreteStrategy)

*/

public class Caesar implements IStrategy {

public String encrypter(String message) {

char[] caracteres = message.toCharArray();

for (int i = 0; i < caracteres.length; i++) {

char c = caracteres[i];

c++;

caracteres[i] = c;

141

caracteres[i] = c;

}

return new String(caracteres);

}

public String decrypter(String message) {

char[] caracteres = message.toCharArray();

for (int i = 0; i < caracteres.length; i++) {

char c = caracteres[i];

c--;

caracteres[i] = c;

}

return new String(caracteres);

}

}

Page 142: DesignPatterns comportement H10 - Université Lavallamontagne/glo3001/DesignPatterns...Patrons de comportement • Memento – Capturer et extraire l’état interne d’un objet •

Stratégie - Exemple/**

* Masque XOR 103 (ConcreteStrategy)

*/

public class Mask implements IStrategy {

public String encrypter(String message) {

char[] caracteres = message.toCharArray();

for (int i = 0; i < caracteres.length; i++) {

int c = caracteres[i];

c = c ^ 103;

caracteres[i] = (char)c;

}

142

}

return new String(caracteres);

}

public String decrypter(String message) {

char[] caracteres = message.toCharArray();

for (int i = 0; i < caracteres.length; i++) {

int c = caracteres[i];

c = c ^ 103;

caracteres[i] = (char)c;

}

return new String(caracteres);

}

}

Page 143: DesignPatterns comportement H10 - Université Lavallamontagne/glo3001/DesignPatterns...Patrons de comportement • Memento – Capturer et extraire l’état interne d’un objet •

Stratégie - Exemple/**

* Message secret (Context)

*/

public class Message {

private IStrategy strategie;

private String message;

public Message() {

this.message = "";

this.strategie = null;

}

143

}

public String getMessage() {

return this.message;

}

public void setMessage(String msg) {

this.message = msg;

}

// ...

Page 144: DesignPatterns comportement H10 - Université Lavallamontagne/glo3001/DesignPatterns...Patrons de comportement • Memento – Capturer et extraire l’état interne d’un objet •

Stratégie - Exemple

// ...

public void setStrategie(IStrategy s) {

this.strategie = s;

}

public void encrypter() {

this.message = this.strategie.encrypter(this.message);

}

144

}

public void decrypter() {

this.message = this.strategie.decrypter(this.message);

}

}

Page 145: DesignPatterns comportement H10 - Université Lavallamontagne/glo3001/DesignPatterns...Patrons de comportement • Memento – Capturer et extraire l’état interne d’un objet •

Stratégie - Exemplepublic class Main {

public static void main(String[] args) {String message = "Bonjour le monde!"; Message msg = new Message();

System.out.println("--- Caesar ---");

msg.setMessage(message);msg.setStrategie(new Caesar());

System.out.println("Message original : " + message);

145

System.out.println("Message original : " + message);msg.encrypter();System.out.println("Message crypté : " + msg.getMessage());msg.decrypter();System.out.println("Message décrypté : " + msg.getMessage());

System.out.println("--- Mask ---");

msg.setMessage(message);msg.setStrategie(new Mask());

System.out.println("Message original : " + message);msg.encrypter();System.out.println("Message crypté : " + msg.getMessage());msg.decrypter();System.out.println("Message décrypté : " + msg.getMessage());

}}

Page 146: DesignPatterns comportement H10 - Université Lavallamontagne/glo3001/DesignPatterns...Patrons de comportement • Memento – Capturer et extraire l’état interne d’un objet •

Template Method

• Définir le squelette d’un algorithme et laisser les sous-classes implanter les détails des étapes

• Problème

– Un processus fait intervenir un algorithme dont – Un processus fait intervenir un algorithme dont certaines étapes peuvent être implantées de différentes façons

– On veut fixer certaines parties de l’algorithme et faire varier d’autres parties

Friday, February 05, 2010 Luc Lamontagne 146

Page 147: DesignPatterns comportement H10 - Université Lavallamontagne/glo3001/DesignPatterns...Patrons de comportement • Memento – Capturer et extraire l’état interne d’un objet •

Template Method

• Solution– Définir les étapes de l’algorithme dans une classe parent

• Concrète : Implantation par défaut des étapes• Abstraite : Pas d’implantation par défaut des étapes

– Une méthode de la classe parent contrôle la séquence d’exécution des étapes (Template Method)

– Une méthode de la classe parent contrôle la séquence d’exécution des étapes (Template Method)

• Cette méthode ne peut être redéfinie par les classes enfant (final)

– La classe parent implante les étapes invariables• Peut également implanter une logique par défaut des étapes variables

– Les classes enfant implantent les étapes variables• Reporter les détails des étapes dans les sous-classes

Friday, February 05, 2010 Luc Lamontagne 147

Page 148: DesignPatterns comportement H10 - Université Lavallamontagne/glo3001/DesignPatterns...Patrons de comportement • Memento – Capturer et extraire l’état interne d’un objet •

Template Method

148

Page 149: DesignPatterns comportement H10 - Université Lavallamontagne/glo3001/DesignPatterns...Patrons de comportement • Memento – Capturer et extraire l’état interne d’un objet •

Template Method

• Conséquences

– Permet de définir le squelette d’un algorithme

– Transfert le contrôle de la séquence d’exécution de l’algorithme à la classe parentde l’algorithme à la classe parent

Friday, February 05, 2010 Luc Lamontagne 149

Page 150: DesignPatterns comportement H10 - Université Lavallamontagne/glo3001/DesignPatterns...Patrons de comportement • Memento – Capturer et extraire l’état interne d’un objet •

Template Method - Exemple

• Algorithme de validation de cartes de crédit

Friday, February 05, 2010 Luc Lamontagne 150

Page 151: DesignPatterns comportement H10 - Université Lavallamontagne/glo3001/DesignPatterns...Patrons de comportement • Memento – Capturer et extraire l’état interne d’un objet •

Template Method - Exemple

• Algorithme de validation de cartes de crédit

– La validation d’une carte de crédit se fait en 4 étapes

• Vérification du nom du détenteur

• Vérification du préfix du numéro de la carte

• Vérification du numéro de la carte

• Vérification de la date d’expiration

– La même séquence est valable pour tout les types de cartes de crédit

– Les méthodes et les conditions de validation diffèrent selon le type de carte

Friday, February 05, 2010 Luc Lamontagne 151

Page 152: DesignPatterns comportement H10 - Université Lavallamontagne/glo3001/DesignPatterns...Patrons de comportement • Memento – Capturer et extraire l’état interne d’un objet •

Template method - Exemple

• Validation d’une carte de crédit

Friday, February 05, 2010 Luc Lamontagne 152

Page 153: DesignPatterns comportement H10 - Université Lavallamontagne/glo3001/DesignPatterns...Patrons de comportement • Memento – Capturer et extraire l’état interne d’un objet •

Template Method - Exemple/**

* Asbtract Class

*/

public abstract class CarteCredit {

private String numero;

private String nom;

private int expiration;

public CarteCredit(String nom, String numero, int expiration) {

this.nom = nom;

this.numero = numero;

153

this.expiration = expiration;

}

public String getNom() {

return this.nom;

}

public String getNumero() {

return this.numero;

}

public int getExpiration() {

return this.expiration;

}

// ...

Page 154: DesignPatterns comportement H10 - Université Lavallamontagne/glo3001/DesignPatterns...Patrons de comportement • Memento – Capturer et extraire l’état interne d’un objet •

Template Method - Exemple

// ...

// Template Method

public final boolean estValide() {

if (nomValide() && prefixValide() && numeroValide() && expirationValide()) {

return true;

} else {

return false;

}

}

154

}

public abstract boolean nomValide();

public abstract boolean prefixValide();

public abstract boolean numeroValide();

public abstract boolean expirationValide();

}

Page 155: DesignPatterns comportement H10 - Université Lavallamontagne/glo3001/DesignPatterns...Patrons de comportement • Memento – Capturer et extraire l’état interne d’un objet •

Template Method - Exemple

/**

* Carte de crédit de type VISA (ConcreteClass)

*/

public class CarteVisa extends CarteCredit {

public CarteVisa(String nom, String numero, int expiration) {

super(nom, numero, expiration);

}

public boolean nomValide() {

155

public boolean nomValide() {

// Vérification du détenteur de la carte

System.out.println("VISA : Vérification nom");

return true;

}

// ...

Page 156: DesignPatterns comportement H10 - Université Lavallamontagne/glo3001/DesignPatterns...Patrons de comportement • Memento – Capturer et extraire l’état interne d’un objet •

Template Method - Exemple

// ...

public boolean prefixValide() {System.out.println("VISA : Vérification préfix");if (getNumero().startsWith(“450")) {

return true;} else {

return false;}

}

156

public boolean expirationValide() {System.out.println("VISA : Vérification date expiration");if (getExpiration() > 1001) {

return true;} else {

return false;}

}

// ...

Page 157: DesignPatterns comportement H10 - Université Lavallamontagne/glo3001/DesignPatterns...Patrons de comportement • Memento – Capturer et extraire l’état interne d’un objet •

Template Method - Exemple// ...

public boolean numeroValide() {System.out.println("VISA : Vérification numéro");if (getNumero().length() == 13) {

int somme = 0;String digit;for (int i = 0; i < getNumero().length(); i++) {

try {digit = getNumero().substring(i, i+1);somme += Integer.parseInt(digit);

} catch (Exception e) {somme += 0;

}

157

} }

if (somme == 50) {return true;

} else {return false;

}} else {

return false;}

}}

Page 158: DesignPatterns comportement H10 - Université Lavallamontagne/glo3001/DesignPatterns...Patrons de comportement • Memento – Capturer et extraire l’état interne d’un objet •

Template Method - Exemple

public class Main {

public static void main(String[] args) {

CarteCredit visa = new CarteVisa("Robert Laberge", "1234532896043", 2009);

if (visa.estValide()) {

System.out.println("Carte VISA appartennant à " + visa.getNom() + " est valide");

} else {

158

System.out.println("Carte VISA appartennant à " + visa.getNom() + " estinvalide");

}

}

}

Page 159: DesignPatterns comportement H10 - Université Lavallamontagne/glo3001/DesignPatterns...Patrons de comportement • Memento – Capturer et extraire l’état interne d’un objet •

Objet null

• Null en programmation– Objet non-existant (i.e pas d’objet)– On ne peut pas invoquer de méthodes– On doit vérifier avant de l’utiliser

• Objet Null– Objet de la classe “non-existante”– Utile si une sous-classes n’est pas disponible– On lui associe un comportement par défaut

• Offre les mêmes méthodes que les autres sous-classes

– Pas de vérification et permet un traitement uniforme

Friday, February 05, 2010 Luc Lamontagne 159

Page 160: DesignPatterns comportement H10 - Université Lavallamontagne/glo3001/DesignPatterns...Patrons de comportement • Memento – Capturer et extraire l’état interne d’un objet •

Objet null

• File logging

Friday, February 05, 2010 Luc Lamontagne 160

Page 161: DesignPatterns comportement H10 - Université Lavallamontagne/glo3001/DesignPatterns...Patrons de comportement • Memento – Capturer et extraire l’état interne d’un objet •

Objet null

public class NullLogger implements Logger {

public void log(String msg) { }

}

public class LoggerTest {public class LoggerTest {

public static void main(String[] args) {

LoggerFactory factory = new LoggerFactory();

Logger logger = factory.getLogger();

logger.log("A Message to Log");

}

}

Friday, February 05, 2010 Luc Lamontagne 161

Page 162: DesignPatterns comportement H10 - Université Lavallamontagne/glo3001/DesignPatterns...Patrons de comportement • Memento – Capturer et extraire l’état interne d’un objet •

La suite…

• Étude des styles architecturaux

– Styles de bases

– Interactionnel

• Maîtrise des principales notions de Java• Maîtrise des principales notions de Java

– Adaptatif

• Utilisé pour décrire les structures

– ...

Friday, February 05, 2010 Luc Lamontagne 162