Design Patterns
Introduction Un pattern (ou patron) est une bonne pratique face à un problème récurrent intervenant dans les différents niveaux du processus: Analyse (Analysis pattern) Architecture (Architecural pattern) Conception (Design pattern) Pourquoi utiliser les patterns Ne pas réinventer. Code facilement compréhensible par d'autres développeurs Réduction de la complexité Catalogue de solutions 2
2- Les patrons de conceptions GoF On distingue trois catégories de patrons de conception selon leur utilisation : création : instanciation et configuration des classes et des objets structuraux : organisation des classes d une application comportementaux : distribution des responsabilités entre objets et description des algorithmes impliqués. 3
2-1 Création 1. Fabrique abstraite (Abstract Factory) 2. Monteur (Builder) 3. Fbi Fabrique (Factory Mthd) Method) 4. Prototype (Prototype) 5. Singleton (Singleton) 4
2-2 Structure 1. Adaptateur (Adapter) 2. Pont (Bridge) 3. Objet composite (Composite) 4. Décorateur (Decorator) 5. Façade (Facade) 6. Poids-mouche ou poids-plume (Flyweight) 7. Proxy (Proxy) 5
2-3 Comportement 1. Chaîne de responsabilité (Chain of responsibility) 2. Commande (Command) 3. Interpréteur (Interpreter) 4. Itérateur (Iterator) 5. Médiateur (Mediator) 6. Mémento (Memento) 7. Observateur (Observer) 8. État (State) 9. Stratégie (Strategy) 10. Patron de méthode (Template Method) 11. Visiteur (Visitor) 6
7 3-Création
Singleton Objectif: S'assurer qu'une classe ne possède qu'une seule instance et définir une méthode qui retourne cette instance public class Singleton { public static Singleton getinstance() { if (instance == null) instance = new Singleton(); return instance; } private Singleton() { } private static Singleton instance; 8 }
Structure Un champ privé qui représente l'instance unique de la classe: instance. Une méthode statique qui retourne l'instance unique. Un constructeur trivial privé (il peut être aussi protected dans le cas de l'héritage). Le client ne peut accéder à l'instance qu' à travers la méthode getinstance() 9
Exemples dans Java SE java.lang.runtime Runtime r= Runtime.getRuntime(); System.out.println("Mémoire libre: " + r.freememory()/(1024*1024)); System.out.println("Nombre processeurs: " + r.availableprocessors()); r.gc(); System.out.println("Mémoire libre: " + r.freememory()/(1024*1024)); System.out.println(«Mémoire totale: " + r.totalmemory()); Java.awt.Desktop java.awt.desktop d = java.awt.desktop.getdesktop(); if (Desktop.isDesktopSupported()) { try { d.browse(new URI("http://www.google.com")); d.edit(new File("d:/note.txt")); d.mail(); } catch (Exception ex) { Logger.getLogger(JavaApplication4.class.getName()).log(Level.SEVERE, null, ex); } } 10
Exemples dans le framework.net La classe DBNull DBNull d1,d2; d1 = DBNull.Value; d2 = DBNull.Value; if (d1 == d2) { Console.WriteLine("d1 et d2 sont identiques"); } 11
Factory Method Le pattern Factory Method permet de déléguer la création d'un objet aux sous classes concrètes d'une classe de base. Aantage Avantage: Dissocier l'implémentation des classes de leur utilisation 12
Structure Objet à créer: de type une interface ou une classe abstraite (IProduit) Une ou plusieurs classes concrètes (ProduitA, ProduitB, ProduitC). Une classe fabrique: ProduitFactory Une méthode de création: IProduit creerproduit(string it(ti type). Conséquences: Le code client est idé indépendant d des classes concrètes (ProduitA, ProduitB, ProduitC), et dépend uniquement de l'interface Iproduit. 13
Exemples dans le Framework.Net WebRequest //WebRequest classe abstraite, classes concrètes: HttpWebRequest,FileWebRequest,FtpWebRequest WebRequest requete = WebRequest.Create("http://localhost"); 14
Exemples dans Java SE DriverManager Connection cnx= DriverManager.getConnection(url); Statement inst= cnx.createstatement(); 15
Abstract Factory Objectif : Fournir une interface pour créer des objets apparentés ou regroupés en familles, sans connaître les classes concrètes responsables de leur instanciation. 16
Participants: IFactory : Fabrique abstraite qui contient les méthodes de création des produits. Factory1, Factory2: implémentent l'interface IFactory. IProduitA et IProduitB: interfaces pour créer des catégories de produits. ProduitA1 et ProduitA2 : classes concrètes qui implémentent IProduitA ProduitB1 et ProduitB2 : classes concrètes qui implémentent l'interface linterface IProduitB La classe Client utilisent les classes abstraites IFactory, IProduitA et IProduitB. Utilisation 17
18 Exemples dans le Framework.Net IHttpHandler et IHttpHandlerFactory
Exemples dans Java SE DocumentBuilderFactory try { String xmlfichier = "doc1.xml"; // obtenir la fabrique de parseurs DocumentBuilderFactory factory =DocumentBuilderFactory.newInstance(); //obtenir le parseur DocumentBuilder builder = factory.newdocumentbuilder(); // Créer l'arborescence DOM du fichier XML Document doc =builder.parse(new File(xmlFichier)); } catch (Exception ex) { Logger.getLogger(JavaApplication4.class.getName()).log(Level.SEVERE, null, ex); } 19
Builder Le pattern Builder sépare la construction d'un objet complexe de sa création. Le même processus de construction peut créer des représentations différentes. le pattern Builder permet de déplacer la construction de l'objet composé en dehors de la classe à instancier. 20
Participants Ibuilder: interface pour les bild builders. Director: une séquence d'opérations à suivre pour créer les produits. Builder: une classe appelée par un Director pour réaliser des parties d'un produits. Produit: objet à construire par parties. Utilisation Construire des objets complexes, sans connaître leur structure. Construire des objets complexes ayant plusieurs représentations et implémentations. 21
Exemples dans le Framework.Net IHttpHandler et IHttpHandlerFactory //WebRequest classe abstraite, classes concrètes: HttpWebRequest,FileWebRequest,FtpWebRequest WebRequest requete = WebRequest.Create("http://localhost"); 22
Exemples dans Java SE DocumentBuilderFactory try { String xmlfichier = "doc1.xml"; // obtenir la fabrique de parseurs DocumentBuilderFactory factory =DocumentBuilderFactory.newInstance(); //obtenir le parseur DocumentBuilder builder = factory.newdocumentbuilder(); // Créer l'arborescence DOM du fichier XML Document doc =builder.parse(new File(xmlFichier)); } catch (Exception ex) { Logger.getLogger(JavaApplication4.class.getName()).log(Level.SEVERE, null, ex); } 23
Prototype L'objectif du pattern prototype est de permettre la création de nouveaux objets bjt par la copie d'un ou de plusieurs exemplaires li appelés prototypes. 24
Exemples dans Java SE L'interface Cloneable,Object.clone() Exemples dans le Framework.Net ICloneable 25
4- Structure L'objectif des patterns de structuration est de séparer l'interface d'un objet ou d'un ensemble d'objets de son implémentation. pé tato 26
Facade L'objectif du pattern façade est de regrouper les interfaces d'un ensemble d'objets en une interface unifiée plus simple à utiliser par le client 27
28 Participants SystemeA, SystemeB et SystemeC: classes du système. Facade: classe qui encapsulent les opérations demandées par le client Client: le client accède au système via la classe Façade. Utilisation Fournir une interface simple d'un système complexe. Diviser un système en couches, la communication entre deux couches différentes peut être réalisée à l'aide des façades. Encapsuler l'implémentation d'un système vis-à-vis de l'extérieur Diminuer le couplage entre le client et le système
29 Adapter Le but du pattern Adapter est de convertir l'interface d'une classe existante en une autre interface attendue par des clients.
Participants ICible: interface utilisée par le client. Adapté: Implémentation qui doit être adaptée. Adapter: adaptateur, adapte l'interface de "Adapté" à l'interface demandée par le client. requete(): opération demandée par le client. Operation(): opération exécutée par Adapté, suite à l'appel de requete() Utilisation Intégrer un composant dans un système dont l'interface ne correspond pas à celle requise par le système. Fournir plusieurs interfaces lors de la conception d'un objet. Implémentations Java : MouseAdapter, WindowAdapter 30
Decorator Objectifs: Ajouter ou modifier dynamiquement des fonctionnalités à une classe. Fournir une alternative à l'héritage pour étendre une classe. 31
Participants Composant: classe dont le comportement doit être modifié. operation(): opération à modifier. IComposant: interface qui identifient les classes qui peuvent être décorées. Decorator : classe qui ajoute ou modifie des fonctionnalités d'un composant. Uili Utilisationi Graphiques, son, video. Une classe que nous souhaitons étendre, mais qui ne peut pas être héritée. 32
Exemples dans le Framework.Net CryptoStream: est de type Stream et possède un objet de type Stream passé comme paramètre au constructeur. BufferedStream Exemple d utilisation du pattern Decorator public partial class Photo : Form { Image image; public Photo() { image = new Bitmap("jup.jpg"); Text = "Jupiter"; this.paint += new PaintEventHandler( dessiner); //InitializeComponent(); } public virtual void dessiner(object srouce, PaintEventArgs e) { e.graphics.drawimage(image, 30, 20);}} public class CadrePhoto: Photo { Photo photo; Color couleur; public CadrePhoto(Photo p,color c) { photo = p; couleur = c; } public override void dessiner(object srouce, PaintEventArgs e) { base.dessiner(srouce, e); e.graphics.drawrectangle(new Pen(couleur,10),25,15,240,225);}} 15 240 225) Photo p= new Photo(); CadrePhoto cp = new CadrePhoto(p, Color.Aqua); Application.Run(cp); 33
Bridge L'objectif du pattern Bridge est de séparer l'aspect représentation d'un objet de son aspect implémentation, ce qui permet à l'implémentation et la représentation d'évoluer indépendamment. 34
Participants ClasseAbstraite: Interface visible par le client, elle contient une référence vers un objet de type Bridge. 35
Composite L'objectif du pattern composite est de définir un cadre de conception d'une composition d'objets arborescente dont la profondeur est variable. 36
Participants Opération: opération à exécuter sur un IComposant. Composant: implémente les opérations applicables sur les composants atomiques. Composite: Implémente les opérations applicables sur une hiérarchie de composants. Client: le client utilise uniquement l'interface Icomposant. Uili Utilisationi 37
FlyWeight L'objectif du pattern Flyweight est de partager de façon efficace un ensemble d'objets important de grain fin. Le pattern flyweight distingue deux états possibles: L'état intrinsèque est partagé par tous les objets L'état extrinsèque est calculé dynamiquement. 38
Participants FlyweightFactory: crée des objets flyweight uniques Flyweight: stocke des attributs intrinsèques qui sont partagés par tous les objets. Utilisation Le système utilise un nombre important d'objets partégés 39
Proxy L objectif du pattern Proxy est de contrôler l accès à un objet en fournissant un intermédiaire i pour cet objet. Le proxy reçoit les requêtes du client, Au moment approprié il envoie ces requêtes au sujet réel (après l'avoir créé lors du premier appel). Comme le proxy et le sujet implémentent la même interface, alors il peuvent être librement interchangeables. 40
Participants ISujet: interface commune aux sujets et au proxy. Sujet: classe représentée par le proxy. Proxy: classe qui permet l'accès à Sujet requete(): opération redirigée via le proxy Types de proxys Proxy virtuel: permet de créer un objet de taille importante au moment approprié. p Proxy d'authentification: vérifie les permissions d'accès à une requête sont valides. Proxy distant: encode les requêtes et les envoie sur le réseau à un objet dans un environnement distant Smart Proxy: modifie la requête avant son envoi. Utilisation 41
5- Comportement L'objectif des patterns de comportement est de fournir des solutions pour distribuer les traitements et les algorithmes entre e les objets
Chain Of Responsability Objectif : Le pattern " Chain of Responsibility" construit une chaîne d objets telle que si un objet de la chaîne ne peut pas répondre à une requête, il puisse la transmettre à son successeur et ainsi de suite jusqu à ce que l un des objets de la chaîne y réponde. 43
Participants Client : classe qui demande l'exécution de la requête IHandler: interface des gestionnaires. Handler1, Handler2, : Gestionnaires. Successeur: lien vers le gestionnaire suivant Requete(): requete demandée par le client. Utilisation 44
Iterator Le pattern Iterator fournit un accès séquentiel à une collection d objets sans se préoccuper de l implantation de cette collection. 45
Observer Le pattern Observer construit une relation entre un objet (le sujet) et des observateurs de sorte que chaque modification du sujet soit notifiée aux observateurs 46
Participants Sujet: classe dont les instances doivent notifier les observateurs lorsque leur état change. IObserver Observer Update Notifier Utilisation 47
Implémentation
public class Client {public static void Exemple1() {Sujet s = new Sujet(); s.attacher(new Observer(s, "O1")); s.attacher(new Observer(s, "O2")); s.attacher(new Observer(s, "O3")); Console.WriteLine("Les observateurs sont créés, Tapez une touche pour modifier l'état du sujet"); Console.ReadKey(); // Modifier l'état du sujet et notifier les observateurs s.etat = "Etat1"; s.notifier(); Console.ReadKey();}} public abstract class IObserver {public abstract void Update();} public class Sujet : ISujet {public string etat { get; set; } } public abstract class ISujet { private List<IObserver> _observateurs = new List<IObserver>(); public void Attacher(IObserver observer){_observateurs.add(observer); } public void detacher(iobserver observer){_observateurs.remove(observe r);} public void Notifier() {foreach (IObserver o in _observateurs){o.update();}}} public class Observer : IObserver { private string _nom, _etat; private Sujet _sujet; public Observer(Sujet sujet, string nom){ this._sujet = sujet; this._nom = nom;} public override void Update() { _etat t = _sujet.etat; t t Console.WriteLine("Observateur: {0}, Etat: {1}",_nom, _etat);} public Sujet sujet{ get { return _sujet; } set { _sujet = value; }}}}