Un peu de Design Pattern Quelques modèles pour développer vite et bien.

Slides:



Advertisements
Présentations similaires
Cours n° 7 Standard Template Library II.
Advertisements

Ex. 1 Quest-ce que cest ? Écris le nom sous la vignette.
C++ 6ème cours Patrick Reuter maître de conférences
1 Quelques précisions sur l'héritage. 2 Signification de super.f() appel à la méthode f() masquée super : désigne l'objet appelant comme s'il était de.
Introspection et Réflexion Manipulation dynamique de code Java.
Au programme du jour …. Un peu plus de structures de données
Cours n° 8 Conception et Programmation à Objets
Langages objet Définitions Traduction des méthodes en C++
Dernière scéance: Des question?????? + Deux exercices.
POO.
Leçon 3 : Héritage IUP 2 Génie Informatique
Introduction à la POO: Les classes vs les objets
Programmation orientée objet
Langage Oriente Objet Cours 4.
COURS DE PROGRAMMATION ORIENTEE OBJET :
POO-L3 H. Fauconnier1 Tableau et héritage Y[] yA=new Y[3]; X[] xA=yA; //ok xA[0]=new Y(); xA[1]=new X(); //non xA[1]=new Z(); //non Object XX[]int[] YZY[]Z[]
Principes de programmation (suite)
IFT1025, Programmation 2 Jian-Yun Nie
Classes abstraites et Interfaces
Mapping Objet-Relationnel
Master 1 SIGLIS Java Lecteur Stéphane Tallard Chapitre 5 – Héritage, Interfaces et Listes génériques.
Leçon 2 : Surcharge des opérateurs IUP 2 Génie Informatique Méthode et Outils pour la Programmation Françoise Greffier Université de Franche-Comté.
Structures de données IFT-2000
Programme de baccalauréat en informatique Programmation Orientée Objets IFT Thierry EUDE Module 7 : Classes et fonctions paramétrables Département.
Conteneurs STL.
Introduction au paradigme orienté-objet (suite)
1 PROTOTYPE PGC++ Courbe_parametrique DÉFINITION.
Design Pattern Memento. Principe : Enregistrer les changements d'états d'un objet Objectif : Pouvoir restituer les états précédents d'un objet.
Design Pattern: Decorator
Chapitre III Héritage. POO-L3 H. Fauconnier2 Chapitre III: Héritage A) Extensions généralités Affectation et transtypage B) Méthodes Surcharge et signature.
Cours 4 Héritage (suite).
COURS DE PROGRAMMATION ORIENTEE OBJET :
1 Fonction : surcharge de sélection La surcharge de sélection consiste à implanter plusieurs méthodes de même nom dans une même classe à condition que.
Héritage Lhéritage permet de spécialiser une classe en définissant une relation de type « est une sorte de ». #include comptebancaire.h class CompteEpargne.
C++ : fonctions et opérateurs
4ième Classe (Mercerdi, 27 octobre) CSI2572. H L'agrégation est un type de relation entre deux classes qui traduit les relations Est composé de... ou.
Structures de données IFT-2000
Structures de données IFT-10541
INF1101 Algorithmes et structures de données
Héritage Licence Informatique Besançon Méthode et Outils pour la Programmation Françoise Greffier.
Héritage et composition
Intention Séparer et extraire les traitements appliquées à différents type de nœuds d’une structure.
LIFI-Java 2004 Séance du Mercredi 22 sept. Cours 3.
La notion de type revisitée en POO
Héritage multiple En langage C++, il est possible d’utiliser l’héritage multiple. Il permet de créer des classes dérivées à partir de plusieurs classes.
11/04/ L'héritage Cours 7 Cours 7.
7ième Classe (Mardi, 24 novembre) CSI2572. Devoir 3 ?
Cours 7 Classes locales Clonage Divers: tableaux.
Cours C++ Fonctions Surcharge d’opérateurs Passage d’arguments
5ième Classe (Mercredi, 19 octobre) Prog CSI2572.
Constructeurs H Batatia. Variable statique Une variable statique est partagée par tous les objets d’une classe.
C++ L’HERITAGE Fayçal BRAÏKI DUT INFORMATIQUE.
Les surcharges d'opérateurs
C# de plus près.  Ce sont globalement les mêmes que Java : ◦ Int(int16, int32), float, double, bool,…  Les classe « communes » sont également les mêmes.
Cours du 5 novembre.
IUT du Limousin L.U.P Michel Vergnaud Programmation Objet - Java.
Héritage H. Batatia. plan Notion (que signifie l’héritage) Ecriture en java Héritage multiple (interdit) Instanciation (partie propre et partie héritée)
Cours 4 (14 octobre) Héritage. Chapitre III Héritage.
Conception de Programmes - IUT de Paris - 1ère année – Cours 6 - Les opérateurs L’amitié Les opérateurs –Introduction –Surcharge par fonction.
Introduction à la programmation objet avec java
2. Reconnaître la proportionnalité
IUT du limousin L.U.P Michel Vergnaud Programmation Objet - Java.
Informatique 2A Langage C 5ème séance. Déroulement de la séance 5 1 ère partie Étude des chaînes de caractères 2 ème partie Les structures 3.
Un exemple complet Panorama sur le C++.
Transcription de la présentation:

Un peu de Design Pattern Quelques modèles pour développer vite et bien

D&Co Un peu de design pattern : le décorateur Principe : étendre les fonctionnalités d'un objet sans utiliser l'héritage et sans modifier les classes Exemple : des desserts On dispose d'une classe Dessert, et on en dérive deux classes par héritage : Gaufre et Crepe. Chaque Dessert a un nom et un prix, et on peut le preparer ().

Ajout de fonctionnalités On souhaite pouvoir ajouter des éléments aux Desserts : du chocolat, de la chantilly, du sucre, éventuellement en portions multiples : double chocolat, sucre + triple chantilly Par héritage, il faudrait créer toutes les classes correspondant aux combinaison Class GaufreDoubleChocoChantilly{} : public Gaufre {}; Etc… Où alors, modifier la classe Dessert pour y ajouter un tableau (conteneur) d'éléments supplémentaires

Ajout de fonctionnalités On utilise un décorateur : classe qui stocke un Dessert et y ajoute l'élément. Un Dessert ainsi décoré reste un Dessert. Implémentation en C++ : class Dessert // c'est une classe abstraite { protected :string _nom; double _prix; public : Dessert(const string &n, double p)_nom(n), _prix(p) {} virtual ~Dessert() {} virtual void preparer()=0; … à suivre

Ajout de fonctionnalités virtual string getName(){return name;} virtual double getPrix() {return prix;} friend ostream& operator<<(ostream &os, dessert &d) { return (os << d.getName() << " : " << d.getPrix() << " euros"); } }; // fin de la classe Dessert

Gaufres et Crêpes class Gaufre : public Dessert { public : Gaufre():dessert("gaufre",2.0){} ~Gaufre(){} void preparer() { cout << "on prepare la gaufre" << endl; } }; Redéfinition de preparer() : Gaufre n'est plus abstraite

Chocolat & Chantilly Rédaction de la classe de décoration : c'est un Dessert, s'applique à un Dessert (un peu comme pour les expressions…) class DecorationDessert : public Dessert { protected : Dessert *_d; // le Dessert à décorer public : DecorationDessert(Dessert *d, const string &n, double px) :Dessert(n,px),_d(d) {} }; Que peut-on dire de cette classe ? Elle est abstraite

Chocolat & Chantilly Le chocolat est une décoration de dessert : class Chocolat : public DecorationDessert { public : Chocolat(dessert *d):DecorationDessert (d,"chocolat",0.2) {} string getName() {return _d->getName()+ dessert::getName();} double getPrix() {return _d->getPrix() + dessert::prix;} void preparer() {cout preparer();} };

Utilisation int main(int argc, char *argv[]) { Dessert *d = new Gaufre(); Dessert *d1 = new Chantilly(d); Dessert *d2 = new Chocolat(new Chocolat(new Crepe())); cout << *d << endl; cout << *d1 << endl; cout << *d2 << endl; cout preparer(); delete d; delete d1; delete d2; return 0; } gaufre : 2 euros gaufre chantilly : 2.2 euros crepe chocolat chocolat : 2.4 euros chauffe le choco prepare la crepe gaufre : 2 euros gaufre chantilly : 2.2 euros crepe chocolat chocolat : 2.4 euros chauffe le choco prepare la crepe On peut ajouter indépendamment de nouveaux desserts et de nouvelles décorations

La Stratégie Autre design-pattern permettant de changer d'algorithme de façon dynamique Illustration : adapter la stratégie d'une IA en cours de programme de manière transparente class Strategie; class IA { long _force; Strategie *_maStrategie; void choixStrategie(Strategie *); public : IA(); ~IA(); void changeForce(long); void jouer(); }; Déclaration de l'existence d'une classe avant définition

La Stratégie class Strategie { public : void jouer(); virtual ~Strategie(); protected : virtual void analyser()=0; virtual void appliquer()=0; }; class Offensive : public Strategie { void analyser(); void appliquer(); }; Class Defensive : public Strategie { void analyser(); void appliquer(); }; Elles sont private ?

La Stratégie : implémentation void Strategie::jouer() { analyser(); appliquer(); } void Offensive::analyser() { cout << "espionner le QG de l'adversaire" << endl; } void Offensive::appliquer() { cout << "lancer une attaque sur le QG adverse" << endl; } void Defensive::analyser() { cout << "surveiller notre QG" << endl; } void Defensive::appliquer() { cout << "defendre le QG" << endl; }

L'IA: implémentation IA::IA():_maStrategie(new Offensive) {} IA::~IA() { delete _maStrategie; } void IA::jouer() { if (_force < 50) { choixStrategie(new Defensive); } _maStrategie->jouer(); } void IA::changeForce(long diff) { _force += diff; }

L'IA: implémentation void IA::choixStrategie(Strategie *s) { if (_maStrategie) { delete _maStrategie; _maStrategie = s; } Dans main, Strategie et son implémentation sont invisibles int main(int argc, char *argv[]) { IA monIA; for (int i = 0; i < 10;i++) { monIA.changeForce(-10); monIA.jouer(); } espionner le QG de l'adversaire lancer une attaque sur le QG adverse espionner le QG de l'adversaire lancer une attaque sur le QG adverse espionner le QG de l'adversaire lancer une attaque sur le QG adverse espionner le QG de l'adversaire lancer une attaque sur le QG adverse espionner le QG de l'adversaire lancer une attaque sur le QG adverse surveiller notre QG defendre le QG surveiller notre QG defendre le QG surveiller notre QG defendre le QG surveiller notre QG defendre le QG surveiller notre QG defendre le QG espionner le QG de l'adversaire lancer une attaque sur le QG adverse espionner le QG de l'adversaire lancer une attaque sur le QG adverse espionner le QG de l'adversaire lancer une attaque sur le QG adverse espionner le QG de l'adversaire lancer une attaque sur le QG adverse espionner le QG de l'adversaire lancer une attaque sur le QG adverse surveiller notre QG defendre le QG surveiller notre QG defendre le QG surveiller notre QG defendre le QG surveiller notre QG defendre le QG surveiller notre QG defendre le QG

Le pool d'objets Mettre à disposition un certain nombre d'instances (disons 10 au maximum) d'une classe pour un programme : Guichet ou distributeur d'instances auprès duquel :  on "emprunte" des objets d'une certaine classe  on restitue ces objets

Le pool d'objets Ce pool d'objet est un singleton (un unique pool pour toute l'application) qui propose  D'emprunter un objet : getObject()  De restituer un "bon" objet : releaseObject()  De restituer un "mauvais" objet releaseBadObject() Par exemple une connexion réseau ou à une BDD

Le pool d'objets class A // la classe des objets à distribuer { static long _count; long _number; public : A() { _number=++_count; } friend ostream& operator<<(ostream& os, const A& a) { os << "objet A" << a._number; return os; } }; long A::_count=0;

Le pool d'objets //ObjectPool.h class ObjectPool // la classe de distribution { std::list _avail; std::list _corrupted; ObjectPool(); // constructeur private static ObjectPool *_instance; // instance unique public : static ObjectPool *getInstance(); // accès à l'instance A* getObject(); // méthode de distribution void releaseObject(A*); // restitution void releaseBadObject(A*) // restitution de mauvais //objet };

Le pool d'objets : singleton //ObjectPool.cpp ObjectPool *ObjectPool::_instance = NULL; ObjectPool *ObjectPool::getInstance() { if (_instance == NULL) { _instance = new ObjectPool(); } return _instance; }

Distribution et restitution //ObjectPool.cpp A* ObjectPool::getObject() { if (_avail.empty()) // empty() : méthode de std::list { return NULL; // ou throw std::exception; } A* val = _avail.front(); _avail.pop_front(); return val; } void ObjectPool::releaseObject(A* a) { _avail.push_front(a); // remise en tête de liste }

Distribution et restitution //ObjectPool.cpp void ObjectPool::releaseBadObject(A* a) { _corrupt.push_back(a); // remise en fin de liste } // le constructeur ObjectPool:ObjectPool():_avail(10) // les 10 objets { std::list ::iterator it; for (it=_avail.begin(); it != _avail.end();it++) { *it = new A; }

Utilisation Les méthodes getObject(), releaseObject() et releaseBadObject() ne sont pas static : ce sont donc des méthodes d'instance.  Appel par le biais d'une instance de ObjectPool Cette instance est unique, on y accède par un pointeur dont le nom est : ObjectPool::getInstance()

Utilisation int main(int argc, char *argv[]) { A *objet1; objet1 = ObjectPool::getInstance()->getObject(); cout << *objet1 << endl; A *objet2 = ObjectPool::getInstance()->getObject(); cout << *objet2 << endl; ObjectPool::getInstance()->releaseObject(objet2); ObjectPool::getInstance()->releaseBadObject(objet1); A *objet3 = ObjectPool::getInstance()->getObject(); cout << *objet3 << endl; return 0; } objet A1 objet A2 objet A1 objet A2