Patrons : Strategy, Decorator, Composite. Patron n o 8 : Strategy. Illustration du problème. Solution

Documents pareils
TP n 2 Concepts de la programmation Objets Master 1 mention IL, semestre 2 Le type Abstrait Pile

Programmation Réseau. Sécurité Java. UFR Informatique jeudi 4 avril 13

Flux de données Lecture/Ecriture Fichiers

Entrées / Sorties. Entrées / Sorties. Entrées/Sorties. System.out. Fonctionnement par flots (stream) Karima Boudaoud IUT- R&T. Terrain connu.

Chapitre 10. Les interfaces Comparable et Comparator 1

Développement Logiciel

Pour plus de détails concernant le protocole TCP conférez vous à la présentation des protocoles Internet enseignée pendant.

ACTIVITÉ DE PROGRAMMATION

Premiers Pas en Programmation Objet : les Classes et les Objets

Encapsulation. L'encapsulation consiste à rendre les membres d'un objet plus ou moins visibles pour les autres objets.

RMI le langage Java XII-1 JMF

Auto-évaluation Programmation en Java

Programmation Internet en Java

TD3: tableaux avancées, première classe et chaînes

Ingénérie logicielle dirigée par les modèles

Structure d un programme et Compilation Notions de classe et d objet Syntaxe

API04 Contribution. Apache Hadoop: Présentation et application dans le domaine des Data Warehouses. Introduction. Architecture

Page 1 sur 5 TP3. Thèmes du TP : l la classe Object. l Vector<T> l tutorial Interfaces. l Stack<T>

Programmer en JAVA. par Tama

Travaux pratiques. Compression en codage de Huffman Organisation d un projet de programmation

1.6- Génération de nombres aléatoires

Corrigé des exercices sur les références

Exceptions. 1 Entrées/sorties. Objectif. Manipuler les exceptions ;

Introduction à Java. Matthieu Herrb CNRS-LAAS. Mars

Gestion distribuée (par sockets) de banque en Java

TP3. Mail. Attention aux fausses manoeuvres lors de ce TP vous pouvez endommager votre mail sur ouindose.

Java Licence Professionnelle CISII, Cours 2 : Classes et Objets

Anne Tasso. Java. Le livre de. premier langage. 10 e édition. Avec 109 exercices corrigés. Groupe Eyrolles, , ISBN :

3. SPÉCIFICATIONS DU LOGICIEL. de l'expression des besoins à la conception. Spécifications fonctionnelles Analyse fonctionnelle et méthodes

Cours intensif Java. 1er cours: de C à Java. Enrica DUCHI LIAFA, Paris 7. Septembre Enrica.Duchi@liafa.jussieu.fr

PROGRAMMATION PAR OBJETS

TP3 : Manipulation et implantation de systèmes de fichiers 1

Exercices sur les interfaces

Cours 1 : Introduction. Langages objets. but du module. contrôle des connaissances. Pourquoi Java? présentation du module. Présentation de Java

TD/TP PAC - Programmation n 3

M06/5/COMSC/SP1/FRE/TZ0/XX INFORMATIQUE NIVEAU MOYEN ÉPREUVE 1. Mardi 2 mai 2006 (après-midi) 1 heure 30 minutes INSTRUCTIONS DESTINÉES AUX CANDIDATS

Le Modèle de Sécurité dans JAVA

Langage Java. Classe de première SI

IRL : Simulation distribuée pour les systèmes embarqués

Java Licence Professionnelle Cours 7 : Classes et méthodes abstraites

TP1 : Initiation à Java et Eclipse

Prénom : Matricule : Sigle et titre du cours Groupe Trimestre INF1101 Algorithmes et structures de données Tous H2004. Loc Jeudi 29/4/2004

1/24. I passer d un problème exprimé en français à la réalisation d un. I expressions arithmétiques. I structures de contrôle (tests, boucles)

Package Java.util Classe générique

ENDNOTE X2 SOMMAIRE. 1. La bibliothèque EndNote 1.1. Créer une nouvelle bibliothèque 1.2. Ouvrir une bibliothèque EndNote 1.3. Fermer une bibliothèque

Le langage C. Séance n 4

Remote Method Invocation (RMI)

Cours d initiation à la programmation en C++ Johann Cuenin

Design patterns. Design patterns - définition. Design patterns - avantages

TD/TP PAC - Programmation n 3

TP, première séquence d exercices.

1 Recherche en table par balayage

Java Licence professionnelle CISII,

Remote Method Invocation Les classes implémentant Serializable

Tp 1 correction. Structures de données (IF2)

LMI 2. Programmation Orientée Objet POO - Cours 9. Said Jabbour. jabbour@cril.univ-artois.fr

Programmation C++ (débutant)/instructions for, while et do...while

1. Structure d un programme C. 2. Commentaire: /*..texte */ On utilise aussi le commentaire du C++ qui est valable pour C: 3.

Programme Compte bancaire (code)

INITIATION AU LANGAGE C SUR PIC DE MICROSHIP

Interfaces graphiques avec l API Swing

Créer le schéma relationnel d une base de données ACCESS

TD Objets distribués n 3 : Windows XP et Visual Studio.NET. Introduction à.net Remoting

Licence Bio Informatique Année Premiers pas. Exercice 1 Hello World parce qu il faut bien commencer par quelque chose...

Utiliser Java sans BlueJ

Plan. Patrons de conception. Motivations. Design Pattern : principe. Philippe Collet

DE L ALGORITHME AU PROGRAMME INTRO AU LANGAGE C 51

Logiciel Libre Cours 3 Fondements: Génie Logiciel

# let rec concat l1 l2 = match l1 with [] -> l2 x::l 1 -> x::(concat l 1 l2);; val concat : a list -> a list -> a list = <fun>

GOL502 Industries de services

Communication inter-processus (IPC) : tubes & sockets. exemples en C et en Java. F. Butelle

Recherche dans un tableau

Programmation système I Les entrées/sorties

Cours 1: Java et les objets

Utilisation d objets : String et ArrayList

Prendre le marteau, le tableau, le mètre, le crayon, la ficelle, le clou, la pointe ;

Lambda! Rémi Forax Univ Paris-Est Marne-la-Vallée

RMI. Remote Method Invocation: permet d'invoquer des méthodes d'objets distants.

Suivant les langages de programmation, modules plus avancés : modules imbriqués modules paramétrés par des modules (foncteurs)

Approche Contract First

P r ob lé m a t iq u e d e la g é n é r icit é. Pr in cip e d e la g é n é r icit é e n Ja v a ( 1 /3 )

Centre CPGE TSI - Safi 2010/2011. Algorithmique et programmation :

Chapitre VI- La validation de la composition.

OCL - Object Constraint Language

Bases de programmation. Cours 5. Structurer les données

Cours d Algorithmique-Programmation 2 e partie (IAP2): programmation 24 octobre 2007impérative 1 / 44 et. structures de données simples

Licence Sciences et Technologies Examen janvier 2010

Cours 14 Les fichiers

Objets et Programmation. origine des langages orientés-objet

Service des ressources informatiques - Conseil Scolaire de District Catholique Centre-Sud Page 1

Algorithmique et Programmation, IMA

Polymorphisme, la classe Object, les package et la visibilité en Java... 1

J2SE Threads, 1ère partie Principe Cycle de vie Création Synchronisation

6 - Le système de gestion de fichiers F. Boyer, UJF-Laboratoire Lig, Fabienne.Boyer@imag.fr

Utilisez Toucan portable pour vos sauvegardes

Les arbres binaires de recherche

Pour signifier qu'une classe fille hérite d'une classe mère, on utilise le mot clé extends class fille extends mère

Calcul Parallèle. Cours 5 - JAVA RMI

TP : Gestion d une image au format PGM

Programmation Par Objets

Transcription:

Patrons : Strategy, Decorator, Composite Pratique de la programmation orientée-objet Michel Schinz 2014 05 05 Patron n o 8 : Strategy 1 2 Illustration du problème Solution On désire écrire une méthode de tri permettant de trier des listes d éléments quelconques : <E> void sort(list<e> list) Pour que cette méthode soit flexible, il faut que l utilisateur puisse spécifier l ordre à utiliser pour le tri. En effet, même pour un type comme les chaînes de caractères il existe plusieurs ordres possibles. Comment faire? La solution consiste bien entendu à utiliser un comparateur pour spécifier l ordre de tri. Pour mémoire, un comparateur a le type Comparator suivant : public interface Comparator<T> { public int compare(t o1, T o2); Pour utiliser un tel comparateur pour le tri, il suffit d ajouter un paramètre le représentant à la méthode : <E> void sort(list<e> list, Comparator<E> comparator) Chaque fois que la méthode de tri doit comparer deux éléments, elle utilise le comparateur. 3 4

Tri pour cruciverbiste Généralisation On peut par exemple utiliser cette méthode pour trier des mots par ordre de longueur ce qui est utile aux cruciverbistes au moyen du comparateur suivant : public final class StringLengthFirstComp implements Comparator<String> { public int compare(string s1, String s2) { int d = Integer.compare(s1.length(), s2.length()); return (d!= 0)? d : s1.compareto(s2); Chaque fois qu une partie d un algorithme doit être interchangeable, il est possible de la représenter au moyen d un objet doté généralement d'une unique méthode. Dans notre exemple, la comparaison de deux objets était la partie variable de l algorithme (de tri), et le comparateur était l objet la représentant. Cette solution est décrite par le patron de conception Strategy aussi appelé Policy. 5 6 Diagramme de classes Exemples réels algorithme à partie variable Context algorithm() strategy Strategy 1 1 ConcreteStrategy1 partie variable de l'algorithme ConcreteStrategy2 La méthode sort de la classe Collections (paquetage java.util) utilise un comparateur pour connaître l ordre de tri à utiliser. Le patron Strategy est aussi souvent utilisé pour spécifier des politiques de sécurité, qui définissent par exemple les opérations qu un programme a le droit d effectuer. C est cette utilisation qui vaut son second nom (Policy) au patron. 7 8

Illustration du problème Patron n o 9 : Decorator Comme nous venons de le voir, la méthode sort de la bibliothèque Java permet de trier une liste selon un ordre spécifié par un comparateur. Cette méthode trie la liste dans l ordre croissant. Toutefois, il peut être parfois utile de la trier par ordre décroissant. Etant donnés une liste et un comparateur pour les éléments de cette liste, comment peut-on trier la liste par ordre décroissant? 9 10 Solution Inverseur de comparateur Pour trier la liste par ordre décroissant selon un comparateur C, il suffit de passer à la méthode sort un comparateur qui soit l inverse de C. Nous dirons que deux comparateurs C 1 et C 2 sont inverses l un de l autre si C 1 retourne une valeur positive quand C 2 en retourne une négative, et inversement. Peut-on programmer une méthode qui, étant donné un comparateur, retourne son inverse? Pour pouvoir définir une telle méthode, la première chose à faire est de définir un nouveau type de comparateur, qui se comporte comme l inverse d un autre comparateur. Cela s avère assez simple : la méthode de comparaison de notre inverseur de comparateur doit appeler celle du comparateur d origine en échangeant les arguments. 11 12

Comparateur inversant public final class InvComparator<E> implements Comparator<E> { private Comparator<E> c; public InvComparator(Comparator<E> c) { this.c = c; @Override public int compare(e s1, E s2) { //??? <E> Comparator<E> inv(comparator<e> c) { return new InvComparator<E>(c); Inverseur de comparateur Bien entendu, il serait également possible d'utiliser une classe imbriquée anonyme pour définir la méthode inv : <E> Comparator<E> inv(final Comparator<E> c){ return new Comparator<E>() { @Override public int compare(e s1, E s2) { return c.compare(s2, s1); ; 13 14 Utilisation de l'inverseur Généralisation Pour trier une liste par ordre décroissant, on peut alors définir la méthode suivante : <E> void invsort(list<e> l, Comparator<E> c) { Collections.sort(l, inv(c)); Cette méthode utilise la méthode de tri de la bibliothèque Java, en inversant au préalable le comparateur passé en argument. Chaque fois que l on désire changer le comportement d un objet sans changer son interface, on peut «l emballer» dans un objet ayant la même interface mais un comportement différent. L objet «emballant» laisse l objet emballé faire le gros du travail, mais modifie son comportement lorsque cela est nécessaire. Cette solution est décrite par le patron Decorator aussi appelé Wrapper. 15 16

Diagramme de classes Exemples réels Component ConcreteComponent1 1 component 1 Decorator1 Les décorateurs sont utilisés dans les bibliothèques de gestion d interfaces graphiques pour ajouter des ornements aux éléments graphiques : bordures, barres de défilement, etc. Le nom Decorator vient de cette utilisation. Comme nous allons le voir maintenant, les décorateurs sont utilisés intensivement dans la bibliothèque Java pour gérer les entrées-sorties. 17 18 Flots Entrées/sorties en Java (digression) Dans la bibliothèque Java, les classes gérant les entréessorties sont regroupées dans le paquetage java.io. La notion centrale de ce paquetage est celle de flot (stream), qui représente une séquence de valeurs à accès séquentiel. C est-à-dire qu il n est en général pas possible de lire ou écrire une valeur à une position quelconque dans un flot, mais seulement à la position courante. 19 20

Sortes de flots Flots d'octets/de caractères Il existe deux sortes de flots : les flots d entrée (input streams) et de sortie (output streams). Les flots d entrée permettent de lire des valeurs depuis une source p.ex. un fichier pour les traiter dans l application. Les flots de sortie permettent d écrire des valeurs de l application dans un puits p.ex. un fichier. Java distingue deux genres de flots, en fonction du type de données qu ils transportent : les flots de caractères et les flots d octets. Les flots de caractères sont représentés par les classes abstraites Reader (entrée) et Writer (sortie) et leurs sous-classes. Les flots d octets sont représentés par les classes abstraites InputStream (entrée) et OutputStream (sortie) et leurs sous-classes. 21 22 Flots concrets Exemple La classe InputStream possède plusieurs sous-classes concrètes qui lisent des octets de plusieurs sources différentes, p.ex. : FileInputStream lit les octets d un fichier, ByteArrayInputStream lit les octets d un tableau. Des classes équivalentes existent pour les flots de sortie, et pour les flots de caractères. // Détermine si un fichier est un fichier classe Java public static void main(string[] args) { try { FileInputStream s = new FileInputStream(args[0]); byte[] b = new byte[4]; int read = s.read(b); boolean isclassfile = (read == b.length && b[0] == (byte)0xca && b[1] == (byte)0xfe && b[2] == (byte)0xba && b[3] == (byte)0xbe); System.out.println(isClassFile); s.close(); catch (IOException e) { e.printstacktrace(); 23 24

Transformation des données Décorateur de compression Lors d opérations d entrée-sortie, il est fréquent de devoir transformer les données lues ou écrites. On peut par exemple vouloir les (dé)compresser, les (dé)crypter ou les (dé)coder. Pour ce faire, la bibliothèque Java fournit plusieurs classes décorateurs qui transforment les données lues ou écrites dans des flots. Par exemple, pour compresser les données au format gzip, il existe la paire de décorateurs GZIPInputStream et GZIPOutputStream, du paquetage java.util.zip. Des décorateurs similaires existent pour d autres formats de compression. 25 26 Mémoire tampon Décorateurs En plus des décorateurs transformant les données, la bibliothèque Java offre des décorateurs plaçant une mémoire tampon (buffer) à l entrée ou à la sortie d un flot, pour améliorer les performances. L idée d une mémoire tampon est de stocker une certaine quantité de données en mémoire avant de les transférer plus loin en une seule fois, p.ex. sur disque. Cela évite les accès trop fréquents au disque, et améliore donc les performances. La classe BufferedInputStream est un décorateur qui ajoute une mémoire tampon à un flot d entrée. La classe BufferedOutputStream est un décorateur qui ajoute une mémoire tampon à un flot de sortie. 27 28

Données complexes La bibliothèque Java fournit également des décorateurs permettant d écrire ou de lire des données plus complexes que de simples octets. Les classes DataInputStream et DataOutputStream permettent les entrées-sorties, sous forme binaire, de données Java entiers, booléens, etc. La classe PrintStream ajoute la possibilité d imprimer des données sous forme textuelle dans un flot de sortie. Exemple // Création d un fichier compressé // contenant 100000 nombres aléatoires // sous forme textuelle. FileOutputStream fos = new FileOutputStream("rand.gz"); GZIPOutputStream zos = new GZIPOutputStream(fos); BufferedOutputStream bos = new BufferedOutputStream(zos); PrintStream ps = new PrintStream(bos); Random r = new Random(); for (int i = 0; i < 100000; ++i) ps.println(r.nextint()); ps.close(); 29 30 Exemple 4513 PrintStream BufferedOutputStream GZIPOutputStream entier 52 53 49 51 10 tableau d octets 49 50 49 10 52 53 49 51 10 mémoire tampon Patron n o 10 : Composite AB A8 02 D1 06 08 01 39 76 09 FileOutputStream données compressées 31 32

Illustration du problème Solution Dans un programme de gestion de base de données, il est fréquent de laisser l utilisateur spécifier un ordre pour trier les données. Cet ordre peut généralement comporter plusieurs critères. Par exemple, on peut vouloir d abord trier par nom de famille, puis par prénom. En interne, un ordre simple peut être représenté par un comparateur. Mais comment représenter les ordres composés de plusieurs critères? Une solution consiste à définir une classe pour représenter un «macro-comparateur» composé de deux comparateurs C 1 et C 2 à appliquer en séquence. Si C 1 déclare que les objets à comparer sont différents, on utilise son résultat, sinon on utilise celui de C 2. Pour qu un tel macro-comparateur soit utilisable comme les autres, il faut qu il implémente l interface Comparator. 33 34 Comparateur composé public final class SeqComparator<E> implements Comparator<E> { private final Comparator<E> c1, c2; public SeqComparator(Comparator<E> c1, Comparator<E> c2) { this.c1 = c1; this.c2 = c2; @Override public int compare(e e1, E e2) { int c = c1.compare(e1, e2); return c!= 0? c : c2.compare(e1, e2); Comparateurs de base public final class StringLengthComparator implements Comparator<String> { public int compare(string s1, String s2){ return Integer.compare(s1.length(), s2.length()); public final class StringLexicalComparator implements Comparator<String> { public int compare(string s1, String s2){ return s1.compareto(s2); 35 36

Comparateur composé Exercice Une fois les deux comparateurs de base définis, on peut les composer au moyen de SeqComparator pour obtenir le comparateur «du cruciverbiste» vu précédemment : Comparator<String> c1 = new StringLengthComparator(); Comparator<String> c2 = new StringLexicalComparator(); Comparator<String> c = new SeqComparator<String>(c1, c2); Définissez un comparateur ordonnant les chaînes par ordre inverse de longueur puis alphabétiquement. 37 38 Programme de dessin Diagramme de classes Dans les programmes de dessin vectoriels, il est fréquent d offrir la possibilité de grouper plusieurs objets en un objet unique. En interne, on peut imaginer avoir une interface Shape représentant les formes géométriques, et une classe l'implémentant par forme ligne, cercle, etc. La classe des groupe de formes implémentera aussi Shape, pour faciliter la programmation. Circle radius center draw() p1 p2 Shape Line * shapes 1 Group draw() draw() draw() 39 40

Représentation mémoire Généralisation dessin représentation Group Group Group Circle Circle Line Line Line Line Chaque fois qu un programme permet à l utilisateur de grouper plusieurs éléments en un macro-élément, il faut s assurer que le type des éléments de base et des macroéléments soit le même. Cela permet de traiter tous les éléments de manière uniforme, et simplifie grandement l organisation interne du programme. C est l idée du patron Composite. 41 42 Diagramme de classes Exemple réel Leaf Component * component 1 Composite Les composants d'une interface Swing bouton, barres de menus, etc. sont tous modélisés par des sous-classes de la classe JComponent. Swing inclut plusieurs composants composites comme le «panneau à onglets», JTabbedPane. Il présente à l utilisateur un ensemble de sous-composants entre lesquels il est possible de naviguer au moyen d onglets. La classe JTabbedPane est elle-même une sous-classe de JComponent. Cela implique entre autres qu il est possible d imbriquer plusieurs panneaux à onglets. 43 44

Arité des méthodes Arité variable (digression) Il est parfois utile d'offrir des méthodes ayant une arité variable, c'est-à-dire acceptant un nombre variable d'arguments. Par exemple, on peut vouloir définir une méthode sum calculant la somme d'un nombre quelconque d'entiers qu'on puisse appeler ainsi : sum(); sum(1); sum(1, 2); etc. Comment faire? 45 46 Utilisation de la surcharge Utilisation des collections Une première idée serait d'utiliser la surcharge pour définir plusieurs versions de la méthode sum : int sum() { return 0; int sum(int v1) { return v1; int sum(int v1, int v2) { return v1 + v2; et ainsi de suite Mais cette technique a bien entendu ses limites, puisqu'elle ne permet pas la définition d'une méthode acceptant un nombre réellement quelconque de valeurs. Elle est de plus fastidieuse à mettre en œuvre... Une deuxième idée serait d'utiliser une collection, p.ex. une liste ou un tableau : int sum(int[] vs) { int sum = 0; for (int v: vs) sum += v; return sum; Cette solution fonctionne mais est lourde à l'usage car chaque appel implique la création d'un tableau, p.ex. : sum(new int[]{ 1, 2, 3 ); 47 48

Arité variable en Java Pour résoudre ces problèmes, Java offre la possibilité de définir des méthodes à arité variable. Cela se fait en ajoutant trois points à la suite du type du dernier argument : int sum(int... vs) { //... calcule la somme de tous // les arguments Cela fait, il devient possible d'appeler la méthode avec un nombre quelconque d'arguments, y compris 0: sum(); // retourne 0 sum(1); // retourne 1 sum(1, 2); // retourne 2 Arité variable en Java Les méthodes à arité variable sont mises en œuvre au moyen de tableaux. Les arguments en nombre variable sont donc passés sous la forme d'un tableau et le paramètre correspondant a un type tableau. Le corps de la méthode sum peut donc s'écrire exactement comme dans la version utilisant des tableaux explicites : int sum(int... vs) { int sum = 0; for (int v: vs) sum += v; return sum; (vs a le type int[]). 49 50 Arité variable en Java Arité minimum Il est valide de passer directement un tableau contenant les arguments à une méthode à arité variable. Ainsi, les deux appels à sum ci-dessous sont équivalents : sum(1, 2, 3); int[] array = new int[]{ 1, 2, 3 ; sum(array); Dans certains cas, une méthode prend un nombre variable d'arguments mais ce nombre ne peut pas être inférieur à une valeur donnée souvent 1. Par exemple, une méthode qui calcule le minimum d'un nombre quelconque d'entiers doit recevoir au moins une valeur, faute de quoi le minimum n'est pas défini. Dans un tel cas, les n arguments obligatoires peuvent être passés comme arguments normaux, tandis que les autres peuvent être passés dans un «argument variable». 51 52

Arité minimum Résumé Ainsi, une méthode calculant le minimum de n entiers, avec n > 0, se définit comme suit : int min(int v1, int... vs) { //??? Le patron Strategy permet de représenter une partie variable d un algorithme par un objet. Le patron Decorator (ou Wrapper) permet de changer le comportement d un objet sans changer son interface. Le patron Composite permet de représenter des objets composés comme des objets simples, simplifiant grandement leur manipulation. * * * L'arité variable permet de définir des méthodes Java qui acceptent un nombre quelconque d'arguments. 53 54