Sommaire Conception Orientée Objetsusers.polytech.unice.fr/~vg/elec4/s8/cours.pdf · Un patron de...

33
Conception Orientée Objets Conception Orientée Objets www.polytech.unice.fr/vg Granet Vincent – [email protected] Polytech – Elec4 – S8/2017 1/118 2/118 Conception Orientée Objets Sommaire Sommaire 1 Sommaire 2 Bibliographie 3 Qualité du logiciel 4 Modularité 5 Étude de cas 6 Conception logicielle O-O 2 UML 3 Patrons de Conception 2/118

Transcript of Sommaire Conception Orientée Objetsusers.polytech.unice.fr/~vg/elec4/s8/cours.pdf · Un patron de...

Conception Orientée Objets

Conception Orientée Objetswww.polytech.unice.fr/~vg

Granet Vincent – [email protected]

Polytech – Elec4 – S8/2017

1/118

2/118

Conception Orientée ObjetsSommaire

Sommaire

1 Sommaire

2 Bibliographie

3 Qualité du logiciel

4 Modularité

5 Étude de cas

6 Conception logicielle O-O

2 UML

3 Patrons de Conception

2/118

55/118

Conception Orientée ObjetsUML

UML

Unified Modeling Language (1995, 2013 - version 2.5)Langage à base de graphiques pour visualiser la conception d’unsystème logicielIssu de précédents langages de modélisation (Booch, OMT,OOSE, ...)Adopté par l’Object Management Group (OMG) - 1997Permet de spécifier, construire, documenter l’application au coursde son développementFondé sur la notion de vue. Un même système peut être vu deplusieurs façons différentes

55/118

56/118

Conception Orientée ObjetsUML

Modèle 4+1 vues

Vue logique

Vue du deploiement

Vue des processus

aspects statiques : classes, objets., ...

aspects dynamiques : interactions, communications

organisation des composants logiciels :

paquetages, fichiers

Vision des finalités du système, scénario d’utilisation

ressources matérielles, et implémentation

sur ces ressources

Vue d’implémentation

Flot d’exécution, synchronisation des tâches, ...

Vue des cas d’utilisation

56/118

57/118

Conception Orientée ObjetsUML

Diagrammes

Les vues se concrétisent en différents types de diagrammes :structurels/statiques :

de classes, d’objets, de composants, de déploiement (ressourcesmatérielles), de paquetages, de structure composites

comportementaux/dynamiques :de séquences, de cas d’utilisation, d’activités, d’interactions

57/118

58/118

Conception Orientée ObjetsUML

Diagramme de classes

Il décrit la structure statique de l’application en termes :d’entités : classes, d’interfaces, d’attributs, de méthodes,de relations entre les entités

58/118

59/118

Conception Orientée ObjetsUML

Diagramme de classes

Différents types de classes

UneClasseAbstraite

− unAttributPrivé : T

+ uneMéthode(p : T) : T

UneClasseGénérique

+ uneMéthodeAbstraite()

# attProtégé : float

+ attPublic : bool

+ uneMéthodeStatique(p:char) : int

+ uneMéthodePublique(p:int)

+ attPubStatique : bool

UneClasse

− attPrivé : int

+ uneMéthodeConcrète()

Un commentaire

T

59/118

60/118

Conception Orientée ObjetsUML

Diagramme de classes

Héritage et Implémentation

Rectangle

Carré

« interface »

Runnable

+ run()

+ run()

uneActivité

60/118

61/118

Conception Orientée ObjetsUML

Diagramme de classes

Dépendance. Utilisation d’une classe par une autre classe, maissans qu’elle soit membre de l’utilisateur.

A

B

+ m(p : A)

61/118

62/118

Conception Orientée ObjetsUML

Diagramme de classes

Association : relation logique (eventuellement nommée) entredeux ou n classes.La relation peut être univoque (sens) ou pas. Les cardinalitéspeuvent être spécifiées.L’application d’une méthode est un exemple d’association.

Entreprise Salariéemploie

1 *

62/118

63/118

Conception Orientée ObjetsUML

Diagramme de classes

Agrégation et Composition sont des associations particulières

Agrégation : relation où une classe est une partie (temporaire)d’une autre classe (le tout/l’agrégat)

PromotionEtudiant1*

Composition : relation où une partie ne peut exister sans le tout

MaisonPièce1..n 1

63/118

64/118

Conception Orientée ObjetsPatrons de Conception

Patrons de Conception

Un patron de conception (design pattern) est un modèle desolution à un problème de conception récurrent.Origine années 70, l’architecte C. Alexander1995, « Design Patterns », Gang of Four (GoF, Erich Gamma,Richard Helm, Ralph Johnson et John Vlissides),Un patron décrit une organisation de classes et les relations quiles lientLes patrons peuvent être combinés entre euxToutefois, ce ne sont pas des composants logiciels directementréutilisables (comme le critique B. Meyer).

64/118

65/118

Conception Orientée ObjetsPatrons de Conception

Les partons du GOF

23 patrons proposés répartis en 3 catégories :1 Les patrons de construction : concernent la création et la

configuration des objets (singleton, fabrique, fabrique abstraite, ...)2 Les patrons de structure : concernent la construction de

structures à base de classes et d’interfaces (adaptateur, objetcomposite, décorateur, ...)

3 Les patrons de comportement : concernent les interactions entreles classes (de méthodes, itérateur, observateur, ...)

65/118

66/118

Conception Orientée ObjetsPatrons de Conception

Les patrons de construction

Les patrons de construction

66/118

67/118

Conception Orientée ObjetsPatrons de Conception

Les patrons de construction

Singleton

but : restreindre l’instanciation d’une classe à un seul objet.utilisation : donner l’accès à des ressources qui n’existent qu’enun seul exemplaireImplémenté par une classe qui contient une méthode de création.Le constructeur de la classe doit être privé (ou protégé) mais paspublic.

− singleton : Singleton

− Singleton()

+ getInstance() : Singleton

Singleton

67/118

68/118

Conception Orientée ObjetsPatrons de Conception

Les patrons de construction

Singleton

template<typename T>class Singleton {public:static T& InstanceUnique() {static T instanceUnique;return instanceUnique;

}};

class Unique : public Singleton<Unique> {public:static Unique & getInstance() {return InstanceUnique();

}};

int main() {Unique u = Unique::getInstance();return EXIT_SUCCESS;

}

68/118

69/118

Conception Orientée ObjetsPatrons de Conception

Les patrons de construction

Fabrique

but : instancier dynamiquement des sous-classes en fonction deparamètres donnés à la fabrique. Cacher les classes concrètes desobjets fabriquésséparer leur instanciation dans des classes dédiéesles fabriques sont uniques, on utilise le patron de conceptionsingleton pour gérer leur création.

Fabrique

+ créerClasse(...) : Classe

instancie instancie

Classe A Classe B

Classe

69/118

70/118

Conception Orientée ObjetsPatrons de Conception

Les patrons de construction

Fabrique (1/2)

class Animal {public:virtual void quiSuisJe() const =0;

};class chat : public Animal {public:void quiSuisJe() const override {std::cout << "je suis un chat" << std::endl;

}};class chien : public Animal {public:void quiSuisJe() const override {std::cout << "je suis un chien" << std::endl;

}};

70/118

71/118

Conception Orientée ObjetsPatrons de Conception

Les patrons de construction

Fabrique (2/2)

class FabriqueAnimal : public Singleton<FabriqueAnimal> {public:static FabriqueAnimal & getInstance() {return InstanceUnique();

}

Animal *getAnimal(std::string typeAnimal) {if (typeAnimal == "chat") return new chat();if (typeAnimal == "chien") return new chien();

}};

int main() {FabriqueAnimal fabrique = FabriqueAnimal::getInstance();Animal *animal = fabrique.getAnimal("chien");animal−>quiSuisJe();animal = fabrique.getAnimal("chat");animal−>quiSuisJe();return EXIT_SUCCESS;

}

71/118

72/118

Conception Orientée ObjetsPatrons de Conception

Les patrons de construction

Fabrique abstraite

but : encapsuler un groupe de fabriques pour créerdynamiquement des objets appartenant à des familles différentes.Le client ne se préoccupe pas de savoir laquelle de ces fabriques adonné un objet concret.

+ créerClasseA(...) : ClasseA

+ créerClasseB(...) : ClasseB

Fabrique A

+ créerClasseA(...) : ClasseA

+ créerClasseB(...) : ClasseB

FabriqueAbstraite

+ créerClasseA(...) : ClasseA

+ créerClasseB(...) : ClasseB

Fabrique B

instancie instancieinstancie instancie

Classe B1Classe A1 Classe A2

Classe B

Classe B2

Classe A

72/118

73/118

Conception Orientée ObjetsPatrons de Conception

Les patrons de construction

Les patrons de construction : Fabrique abstraite

Jeu de personnes de différentes époques avec des soldats et desofficiersCréation des personnages, on veut éviter :

if (epoque=="Rome") s = new legionnaire();else if (epoque=="Napoléonienne") s = new grognard();

mais écrire plutôt :

Soldat * creerSoldats(FabriqueAbstraite *f) {return f−>getSoldat();

}s = creerSoldats(fr); // où fr est une fabrique de romains

73/118

74/118

Conception Orientée ObjetsPatrons de Conception

Les patrons de construction

Fabrique Abstraite (1/4)

class FabriqueAbstraite {public:virtual Soldat *getSoldat() const=0;virtual Officier *getOfficier() const=0;

};

class Soldat {public:virtual void quiSuisJe() const =0;

};

class Officier {public:virtual void quiSuisJe() const =0;

};

74/118

75/118

Conception Orientée ObjetsPatrons de Conception

Les patrons de construction

Fabrique Abstraite (2/4)

class legionnaire : public Soldat {public:void quiSuisJe() const override {std::cout << "je suis un légionnaire" << std::endl;

}};class centurion : public Officier {public:void quiSuisJe() const override {std::cout << "je suis un centurion" << std::endl;

}};class grognard : public Soldat {public:void quiSuisJe() const override {std::cout << "je suis un grognard" << std::endl;

}};class general : public Officier {public:void quiSuisJe() const override {std::cout << "je suis un général" << std::endl;

}};

75/118

76/118

Conception Orientée ObjetsPatrons de Conception

Les patrons de construction

Fabrique Abstraite (3/4)

class FabriqueRome : public FabriqueAbstraite,public Singleton<FabriqueRome>

{public:

static FabriqueRome *getInstance() {return InstanceUnique();

}

Soldat *getSoldat() const override {return new legionnaire();

}

Officier *getOfficier() const override {return new centurion();

}};

// FabriqueNapoléonienne sur le même modèle// ....

76/118

77/118

Conception Orientée ObjetsPatrons de Conception

Les patrons de construction

Fabrique Abstraite - Utilisation (4/4)

Soldat * creerSoldats(FabriqueAbstraite *f) {return f−>getSoldat();

}

Officier * creerOfficiers(FabriqueAbstraite *f) {return f−>getOfficier();

}

int main() {FabriqueAbstraite *fr = FabriqueRome::getInstance();FabriqueAbstraite *fn = FabriqueNapoléonienne::getInstance();

Soldat *s = creerSoldats(fr);s−>quiSuisJe(); // un légionnaires = creerSoldats(fn);s−>quiSuisJe(); // un grognardOfficier *o = creerOfficiers(fn);o−>quiSuisJe(); // un généralreturn EXIT_SUCCESS;

}

77/118

78/118

Conception Orientée ObjetsPatrons de Conception

Les patrons de structure

Les patrons de structure

78/118

79/118

Conception Orientée ObjetsPatrons de Conception

Les patrons de structure

Adaptateur

but : faire collaborer des classes dont les interfaces sontincompatibles – utiliser un instance d’une classe A (la cible), laoù celle d’une classe B (l’adapté) est requiseen C++ l’interface sera une classe abstraite (virtuelle)utilisation : adapter une classe d’une API à des besoinsparticuliersdeux formes : adaptateur de classe – adaptateur d’objet

79/118

80/118

Conception Orientée ObjetsPatrons de Conception

Les patrons de structure

1 - Adaptateur de classe

La classe Adaptateur hérite à la fois de l’adapté et de la cible

+ opération()

« Interface »

CibleAdapté

+ opérationSpécifique()

Adaptateur

+ opération()

client

« privé »

80/118

81/118

Conception Orientée ObjetsPatrons de Conception

Les patrons de structure

Une Api propose une classe TraceurDeTexte qui dessine dutexte dans un contexte graphique

L’adapté

class TraceurDeTexte {...public:void dessinerTexte(std::string s) const {...

};};

81/118

82/118

Conception Orientée ObjetsPatrons de Conception

Les patrons de structure

On écrit une application qui dessine des formes géométriques.Elles implémentent la classe Dessinable.

La cible

class Dessinable {public:virtual void dessine() const =0;

};

class Rectangle : public Dessinable {public:void dessine() const override { ... }

};

class Ellipse : public Dessinable {public:void dessine() const override { ... }

};

82/118

83/118

Conception Orientée ObjetsPatrons de Conception

Les patrons de structure

L’adaptateur

class AdaptateurTDT : public Dessinable, private TraceurDeTexte {private:std::string texte;

public:AdaptateurTDT(std::string t) : texte(t) {}void dessine() const { TraceurDeTexte::dessinerTexte(texte); }

};

Utilisation

Dessinable *formes[] = { new Rectangle(),new AdaptateurTDT("du texte"),new Ellipse()

};

for (Dessinable * f : formes) f−>dessine();

83/118

84/118

Conception Orientée ObjetsPatrons de Conception

Les patrons de structure

2 - Adaptateur d’objet

Une instance de l’adapté est agrégée à la classe Adaptateur

+ opération()

« Interface »

Cible

Adapté

+ opérationSpécifique()

Adaptateur

+ opération()

client

84/118

85/118

Conception Orientée ObjetsPatrons de Conception

Les patrons de structure

On possède une classe virtuelle Pile et une implémentation d’unestructure de liste. On crée un adaptateur pour mettre en œuvrela notion de pile à l’aide d’une liste

La cible

#include <exception>

class PileVideException : public std::exception { ... };

template<typename T>class Pile {public:virtual bool estVide() const =0;virtual void empiler(T &x) =0;virtual void depiler() throw (PileVideException) =0;virtual T sommet() const throw (PileVideException) =0;

};

85/118

86/118

Conception Orientée ObjetsPatrons de Conception

Les patrons de structure

L’adaptateur

template<typename T>class PileL : Pile<T> {private:std::list<T> l; // agrégation de l’adapté

public:bool estVide() const override {return this−>l.size()==0;

}void empiler(T &x) override {this−>l.push_front(x);

}void depiler() throw (PileVideException) override {if (this−>estVide()) throw PileVideException();this−>l.pop_front();

}T sommet() const throw (PileVideException) override {if (this−>estVide()) throw PileVideException();return this−>l.front();

}};

86/118

87/118

Conception Orientée ObjetsPatrons de Conception

Les patrons de structure

Objet composite

but : Utiliser de la même façon des objets différents appartenantà une même structure (polymorphisme)exemple : Un arbre formé de noeuds et de feuilles

1 2 9

8 7

100

200

87/118

88/118

Conception Orientée ObjetsPatrons de Conception

Les patrons de structure

Objet composite

+ opération() + opération()

ItemSimple

+ ajouter(item : Item)

+ supprimer(item : Item)

...

+ opération()

Item

ItemComposite

*

88/118

89/118

Conception Orientée ObjetsPatrons de Conception

Les patrons de structure

l’Item

template<typename T>class arbre {protected:T valeur;

public:arbre (T n) : valeur(n) {};

T getValeur() const {return this−>valeur;

}

virtual std::string toString() const {std::ostringstream s;s << "(" << this−>getValeur() << ")";return s.str();

}};

89/118

90/118

Conception Orientée ObjetsPatrons de Conception

Les patrons de structure

l’Item Composite

template<typename T>class noeud : public arbre<T> {protected:std::vector<arbre<T> *> sousArbres;

public:noeud(T n) : arbre<T>(n) { };void ajouter(arbre<T> *a) {this−>sousArbres.push_back(a);

}

std::string toString() const override {std::ostringstream s;s << "[ " << arbre<T>::getValeur() << " − ";for (const arbre<T> * x : this−>sousArbres)s << x−>toString() << " "; // <= LIAISON DYNAMIQUE

s << "]";return s.str();

};};

90/118

91/118

Conception Orientée ObjetsPatrons de Conception

Les patrons de structure

l’Item Simple

template<typename T>class feuille : public arbre<T> {public:feuille(T n) : arbre<T>(n) {};

};// exemple d’utilisationint main() {noeud<int> *n1 = new noeud<int>(100);noeud<int> *n2 = new noeud<int>(200);n2−>ajouter(new feuille<int>(8));n2−>ajouter(new feuille<int>(7));

n1−>ajouter(new feuille<int>(1));n1−>ajouter(new feuille<int>(2));n1−>ajouter(n2);n1−>ajouter(new feuille<int>(9));// écriture de l’arbre sur la sortie standardstd::cout << n1−>toString() << std::endl;return EXIT_SUCCESS;

}// résultat : [ 100 - (1) (2) [ 200 - (8) (7) ] (9) ]

91/118

92/118

Conception Orientée ObjetsPatrons de Conception

Les patrons de structure

Décorateur

but :ajouter dynamiquement de nouvelles fonctionnalités à un objetéviter de créer un graphe d’héritage trop importantfournir la même interface que le composant décoré

Le décorateur agrège le composant qu’il décoreExemple : les classes DataInputStream et DataOutputStream del’api Java.

92/118

93/118

Conception Orientée ObjetsPatrons de Conception

Les patrons de structure

Schéma Décorateur

Composant

à décorer

+ opération()

Composant

ComposantConcret

+ opération()

+ opération()

Décorateur1

+ DécorateurConcret1(c : Composant)

+ opération()

DécorateurConcret1 DécorateurConcret2

93/118

94/118

Conception Orientée ObjetsPatrons de Conception

Les patrons de structure

le composant à décorer

class glace {public:virtual double getPrix() const =0;

};

class glace_simple : public glace {protected:double prix;

public:glace_simple(double p=3.00) : prix(p) {}

double getPrix() const override {return this−>prix;

}};

94/118

95/118

Conception Orientée ObjetsPatrons de Conception

Les patrons de structure

le décorateur

class topping : public glace {protected:double prix;glace *base;

public:topping(glace *g, double p) : base(g), prix(p) {}

double getPrix() const {return this−>base−>getPrix() + this−>prix;

}};

95/118

96/118

Conception Orientée ObjetsPatrons de Conception

Les patrons de structure

des décorateurs concrets

class smarties : public topping {public:smarties(glace *g, double prix=1.0) : topping(g,prix) {}

};

class sauce_caramel : public topping {public:sauce_caramel(glace *g, double prix=2.0) : topping(g,prix) {}

};

class meringue : public topping {public:meringue(glace *g, double prix=3.0) : topping(g,prix) {}

};

96/118

97/118

Conception Orientée ObjetsPatrons de Conception

Les patrons de structure

Utilisation

int main() {glace *commande[] = {

new glace_simple(), // 3enew smarties(new glace_simple()), // 4enew smarties(new sauce_caramel(new glace_simple())), // 6enew meringue(new sauce_caramel(new glace_simple())), // 8e

};

double prix=0;for (auto c : commande) prix += c−>getPrix();std::cout << prix << std::endl;

return EXIT_SUCCESS;}

// Prix de la commande 21e (pas cher)

97/118

98/118

Conception Orientée ObjetsPatrons de Conception

Les patrons de comportement

Les patrons de comportement

98/118

99/118

Conception Orientée ObjetsPatrons de Conception

Les patrons de comportement

De méthode

but : Spécialiser un algorithme général d’une classe abstraite dansles classes héritièresintérêt : fournir plusieurs variantes d’un algorithme sans changersa structure générale

+ m1(...)

+ algorithme(...)

+ m2(...)

+ m3(...)

P_De_Méthode

+ m1(...)

+ m2(...)

P_De_Méthode

+ m3(...)

99/118

100/118

Conception Orientée ObjetsPatrons de Conception

Les patrons de comportement

Système Interactif Multi-Panel

class State {public:virtual bool correct() const =0;virtual void display() const =0;virtual void message() const =0;virtual void read() =0;virtual void process() const =0;

void execute() {bool ok = false;do {display();read();ok = correct();if (!ok) message();

} while (!ok);process();

}};

100/118

101/118

Conception Orientée ObjetsPatrons de Conception

Les patrons de comportement

Spécialisation d’« execute »

class Enquiry_On_Flights : public State {public :// Rôle : affiche le panel associé à l’état courantvoid display() const override {// affichage spécifique pour l’état Enquiry_On_Flights

}// redéfinition des autres méthodes ...// ...// MAIS pas de la méthode « execute() »

};

101/118

102/118

Conception Orientée ObjetsPatrons de Conception

Les patrons de comportement

Itérateur

but : donner un accès séquentiel à tous les éléments d’unestructure de données (i.e. conteneur), tout en masquant sareprésentation interne.

T

T

+ getItérateur() : Itérateur

Conteneur

T

T

+ premier() : T

+ fin() : booléen

+ suivant() : T

+ getItérateur() : Itérateur

ConteneurConcretItérateurConcret

parcourt# posCourante

+ fin() : booléen

+ premier() : T

Itérateur

+ suivant() : T

return ItérateurConcret()

102/118

103/118

Conception Orientée ObjetsPatrons de Conception

Les patrons de comportement

Stratégie

but : permettre l’échange dynamique d’algorithmes(appelés stratégies) d’une même familleUn environnement peut appliquer différentes stratégies sansconnaître les classes concrètes

StratégieConcrète1 StratégieConcrète2

+ stratégie()

1

− strat : Stratégie

+ stratégie()

+ stratégie()

StratégieEnvironnement

103/118

104/118

Conception Orientée ObjetsPatrons de Conception

Les patrons de comportement

Les stratégies

template<typename T>class strategie {public:virtual void trier(T *t) const =0;

};template<typename T>class QuickSort : public strategie<T> {public:void trier(T *t) const override {// algorithme quickSort

}};template<typename T>class ShellSort : public strategie<T> {public:void trier(T *t) const override {// algorithme ShellSort

}};template<typename T>class BubbleSort : public strategie<T> {public:void trier(T *t) const override {// algorithme BubbleSort

}};

104/118

105/118

Conception Orientée ObjetsPatrons de Conception

Les patrons de comportement

L’environnement d’utilisation

template<typename T>class Trieur {private:strategie<T> *strat;T *tab;

public:Trieur(strategie<T> *s, T *t) : strat(s), tab(t) {};void trier() { this−>strat−>trier(this−>tab); }

};int main() {int tab[] = { ... };

QuickSort<int> quicksort;ShellSort<int> shellsort;BubbleSort<int> bubblesort;

Trieur t1(&quicksort, tab);Trieur t2(&shellsort, tab);Trieur t3(&bubblesort, tab);

t1.trier(); t2.trier(); t3.trier();return EXIT_SUCCESS;

}

105/118

106/118

Conception Orientée ObjetsPatrons de Conception

Les patrons de comportement

Mais beaucoup plus simple avec des valeurs fonctionnelles

template<typename T>class Trieur {private:std::function<void(T *)> strat;T *tab;

public:Trieur(auto s, T *t) : strat(s), tab(t) {};void trier() { this−>strat(this−>tab); }

};

int main() {int tab[] = { ... };

Trieur<int> t1( [] (int *t) −> void { /* algo quicksort */}, tab);Trieur<int> t2( [] (int *t) −> void { /* algo shellsort */}, tab);Trieur<int> t3( [] (int *t) −> void { /* algo bubblesort */}, tab);

t1.trier(); t2.trier(); t3.trier();

return EXIT_SUCCESS;}

106/118

107/118

Conception Orientée ObjetsPatrons de Conception

Les patrons de comportement

Observateur

but :Créer une dépendance entre plusieurs objets, les observateurs, etl’état d’un objet particulier, l’observéLes observateurs s’enregistrent auprès de l’observéQuand l’état de l’observé change, les observateurs en sontinformés, et peuvent se synchroniser.

Intérêt : éviter un couplage fort entre observateurs et observé (cedernier ne connaît pas le type concret des observateurs)Utilisé pour les IHM avec le modèle MVC (modèle=observé,vue(s)=observateur(s))

107/118

108/118

Conception Orientée ObjetsPatrons de Conception

Les patrons de comportement

Observateur

client

+ getEtat()

+ setEtat()

Observé

− état

change Etat

+ ajouterObservateur(obs)

+ notifierObservateurs()

Observable *

+ update()

Observateur

« Abstraite »

UnObservateur

+ update()

synchronisation de this avec

l’état de l’oberservéappelle notifierObservateurs

108/118

109/118

Conception Orientée ObjetsPatrons de Conception

Les patrons de comportement

L’observé

#ifndef OBSERVABLE_HPP#define OBSERVABLE_HPP

#include <list>#include "Observateur.hpp"

template<typename T>class Observable {private:std::list<Observateur<T> *> list_observateurs;

public:void notifierObservateurs(T info) {for (auto obs : this−>list_observateurs) obs−>update(info);

}

void ajouterObservateur(Observateur<T> * observateur) {this−>list_observateurs.push_back(observateur);

}};#endif

109/118

110/118

Conception Orientée ObjetsPatrons de Conception

Les patrons de comportement

Les observateurs

#ifndef OBSERVER_HPP#define OBSERVER_HPP

template<typename T>class Observateur {public:virtual void update(T info) =0;

};

#endif

110/118

111/118

Conception Orientée ObjetsPatrons de Conception

Les patrons de comportement

Visiteur

but : séparer la définition d’une structure de données de celle desalgorithmes qui la manipulent.la structure de données est une composition d’éléments quiacceptent la visite de visiteursles visiteurs portent les algorithmes de traitement à appliquer surles différents élémentsintérêt : permet d’appliquer des algorithmes différents sur leséléments

111/118

112/118

Conception Orientée ObjetsPatrons de Conception

Les patrons de comportement

Visiteur

ElémentA

« abstraite »

Visiteur

+ visiter(e: ElémentA)

Visiteur1 Visiteur2

+ visiter(e: ElémentA)

+ visiter(e: ElémentB)

+ visiter(e: ElémentA)

+ visiter(e: ElémentB)

Structure

*

ElémentB

+ visiter(e: ElémentB)

+ accepter(v: Visiteur)+ accepter(v: Visiteur)

« abstraite »Elément

+ accepter(: Visiteur)

+ visiter(v: Visiteur)

v.visiter(this) v.visiter(this)

finpourtout

pourtout Élément e de Structuree.accepter(v)

112/118

113/118

Conception Orientée ObjetsPatrons de Conception

Les patrons de comportement

Un appartement Fn est formé de n −1 chambres et d’un séjour, plusune cuisine et une salle de bain.

class Appartement {private:std::vector<Piece *> lesPieces;

public:Appartement(int nbPieces) {// les chambresfor (int i=1; i<nbPieces; i++)this−>lesPieces.push_back(new Chambre(std::to_string(i)));

// les autres piècesthis−>lesPieces.push_back(new Sdb());this−>lesPieces.push_back(new Cuisine());this−>lesPieces.push_back(new Salon());

}

// Rôle : visiter toutes les pièces de l’appartement courantvoid visiter(PieceVisiteur *v) const {for (Piece *p : this−>lesPieces)p−>accepter(v);

}};

113/118

114/118

Conception Orientée ObjetsPatrons de Conception

Les patrons de comportement

class Piece {public:virtual void accepter(PieceVisiteur *visiteur) =0;

};

class Chambre : public Piece {private:std::string nom;

public:Chambre(std::string n) : nom(n) {}

std::string getNom() {return this−>nom;

}

void accepter(PieceVisiteur *visiteur) override {visiteur−>visiter(this);

}};

114/118

115/118

Conception Orientée ObjetsPatrons de Conception

Les patrons de comportement

class Cuisine : public Piece {public:void accepter(PieceVisiteur *visiteur) override {visiteur−>visiter(this);

}};

class Salon : public Piece {public:void accepter(PieceVisiteur *visiteur) override {visiteur−>visiter(this);

}};

class Sdb : public Piece {public:void accepter(PieceVisiteur *visiteur) override {visiteur−>visiter(this);

}};

115/118

116/118

Conception Orientée ObjetsPatrons de Conception

Les patrons de comportement

Le visiteur abstrait

class PieceVisiteur {public:virtual void visiter(Chambre *chambre) =0;virtual void visiter(Cuisine *cuisine) =0;virtual void visiter(Sdb *sdb) =0;virtual void visiter(Salon *sejour) =0;

};

116/118

117/118

Conception Orientée ObjetsPatrons de Conception

Les patrons de comportement

Un agent immobilier

class AgentImmobilierVisiteur : public PieceVisiteur {public:void visiter(Chambre *chambre) override {std::cout << "La chambre : " << chambre−>getNom() << std::endl;

}

void visiter(Cuisine *cuisine) override {std::cout << "La cuisine" << std::endl;

}

void visiter(Sdb *sdb) override {std::cout << "La salle de bain" << std::endl;

}

void visiter(Salon *sejour) override {std::cout << "Le sejour" << std::endl;

}};

117/118

118/118

Conception Orientée ObjetsPatrons de Conception

Les patrons de comportement

Un agent immobilier

int main() {Appartement appart(3);PieceVisiteur *agentImmobilier = new AgentImmobilierVisiteur();

appart.visiter(agentImmobilier);return EXIT_SUCCESS;

}

118/118