sommaire conception orientée objetsusers.polytech.unice.fr/~vg/elec4/s8/cours.pdf · un patron de...
TRANSCRIPT
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