Patron Visiteur Gestion de clients

Documents pareils
OpenPaaS Le réseau social d'entreprise

TP Programmation Java / JDBC / Oracle

Java DataBaseConnectivity

Programmation d application Bases de données avec Java

Introduction à JDBC. Accès aux bases de données en Java

Package Java.util Classe générique

La persistance des données dans les applications : DAO, JPA, Hibernate... COMPIL 2010 francois.jannin@inp-toulouse.fr 1

Accès aux bases de données

Travaux Pratiques : Lucène - Gestion d un index plein texte

Guide d utilisation de la bibliothèque en ligne du FMI Création d un livre personnalisé

UML Diagramme de communication (communication diagram) Emmanuel Pichon 2013

Application BdD et JDBC. Introduction 1/28. I Dans tout les cas, une seule problématique. I Quelques alternatives :

Création d un service web avec NetBeans 5.5 et SJAS 9

Architecture applicative et Cartographie

JDBC le langage Java XVI-1 JMF

Introduction au langage de programmation Java

Tutoriel d installation de Hibernate avec Eclipse

1. Langage de programmation Java

Création et Gestion des tables

TP3 : Etude de cas Talend

Programmation Objet Java Correction

Premiers Pas en Programmation Objet : les Classes et les Objets

Oracle Décisionnel : Modèle OLAP et Vue matérialisée D BILEK

Java - MySQL. Code: java-mysql

Olivier Mondet

Le langage SQL pour Oracle - partie 1 : SQL comme LDD

MySQL avec Mac OS X. Quelques manipulations avec le terminal sont nécessaires si une version de MySQL est déjà lancée:

Arbres binaires de recherche

UML (Paquetage) Unified Modeling Language

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

Modélisation et Gestion des bases de données avec mysql workbench

Planifier les rapports d

LES OUTILS D ALIMENTATION DU REFERENTIEL DE DB-MAIN

Déploiement de SAS Foundation

ECR_DESCRIPTION CHAR(80), ECR_MONTANT NUMBER(10,2) NOT NULL, ECR_SENS CHAR(1) NOT NULL) ;

Le langage SQL (première partie) c Olivier Caron

Les bases de données

Tutoriel Création d une source Cydia et compilation des packages sous Linux

Cahier Technique. «Développer une application intranet pour la gestion des stages des étudiants» Antonin AILLET. Remi DEVES

MS SQL Express 2005 Sauvegarde des données

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

Ingénierie Dirigée par les Modèles. Editeurs de modèles. (Eclipse Modeling Tools) Jean-Philippe Babau

KPI (Key Performance Indicator) dans MOSS

Cours de Master Recherche

Serveur d'archivage 2007 Installation et utilisation de la BD exist

Java et les bases de données: JDBC: Java DataBase Connectivity SQLJ: Embedded SQL in Java. Michel Bonjour

Programmer en JAVA. par Tama

Module Administration BD Chapitre 1 : Surcouche procédurale dans les SGBDS

Anne Tasso. Java. Le livre de. premier langage. 6 e édition. Groupe Eyrolles, 2000, 2002, 2005, 2006, 2008, 2010, ISBN :

Warren PAULUS. Android SDK et Android x86

Configurer la supervision pour une base MS SQL Server Viadéis Services

Java Licence Professionnelle CISII,

Logiciel de gestion de caisse et d ardoises

Connexion à SQL Server 2005 à partir du serveur d application SJSAS 9 Utilisation d une interface JDBC

C f tracée ci- contre est la représentation graphique d une

Cours iguess. inotes v10.1

Développement mobile MIDP 2.0 Mobile 3D Graphics API (M3G) JSR 184. Frédéric BERTIN

Exploitation de bases de données relationnelles et orientées objet IFT287

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

Mysql. Les requêtes préparées Prepared statements

Les structures de données. Rajae El Ouazzani

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

TP3 : Creation de tables 1 seance

MODE OPERATOIRE OPENOFFICE BASE

Les arbres binaires de recherche

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

Jade. Projet Intelligence Artificielle «Devine à quoi je pense»

INSTITUT NATIONAL DES TELECOMMUNICATIONS CONTROLE DES CONNAISSANCES. 2. Les questions sont indépendantes les unes des autres.

E.I.S : Un outil performant pour I'analyse du risque en Assurance

Bases de Données NoSQL

Développement Logiciel

Cours Bases de données 2ème année IUT

Description pas à pas des différents processus d installation, configuration, saisie des résultats et export des données.

Java et les bases de données

Bases de Données relationnelles et leurs systèmes de Gestion

CREATION WEB DYNAMIQUE

Extension SSO Java. Cette note technique décrit la configuration et la mise en œuvre du filtre de custom SSO Java.

Meta Object Facility. Plan

CONCOURS DE L AGRÉGATION INTERNE «ÉCONOMIE ET GESTION» SESSION 2015 SECONDE ÉPREUVE

Diagrammes de Package, de déploiement et de composants UML

Performance web. Mesurer. Analyser. Optimiser. Benjamin Lampérier - Benoît Goyheneche. RMLL Beauvais. 8 Juillet 2015

Master Exploration Informatique des données DataWareHouse

Java 1.5 : principales nouveautés

Exclusion Mutuelle. Arnaud Labourel Courriel : arnaud.labourel@lif.univ-mrs.fr. Université de Provence. 9 février 2011

Découvrir l'ordinateur (niveau 2)

Connectivité aux bases de données Java (JDBC)

Cours Informatique Master STEP

Manuel d utilisation 26 juin Tâche à effectuer : écrire un algorithme 2

BIRT (Business Intelligence and Reporting Tools)

La base de données XML exist. A. Belaïd

Guide de configuration d'une classe

Une introduction à la technologie EJB (2/3)

TP Contraintes - Triggers

Administration de Bases de Données : Optimisation

Guide du/de la candidat/e pour l élaboration du dossier ciblé

Un ordonnanceur stupide

Introduction à Java. Matthieu Herrb CNRS-LAAS. Mars

Bases de données Outils de gestion

Programmation Par Objets

Transcription:

Patron Visiteur Gestion de clients Denis Conan et Christian Bac Revision : 1985 CSC4102 Télécom SudParis Mardi 25 janvier 2011

Avertissement : cet exemple de spécification, de conception et mise en œuvre de patron de conception correspond à un sujet donné en contrôle final, première session, du module CSC4002 il y a quelques années. Par conséquent, le programme ayant changé depuis, il y manque des éléments, comme la préparation des tests d intégration. Par ailleurs, la réalisation est très incomplète. Enfin, notez que le code de cet exemple est disponible dans un module Maven associé. 1 Cahier des charges Nous proposons l analyse d un cas d étude que nous présentons ci-après et qui démontre l utilisation d un patron de conception : le patron de conception «Visiteur». Étude de cas. Le patron de conception «Visiteur» propose une manière de séparer lors de la conception et de la programmation d un côté la gestion de données organisées dans des collections imbriquées et de l autre côté les algorithmes qui s appliquent sur les données référencées dans ces collections. Dans notre cas d étude dont le diagramme de classes est présenté dans la figure 1, les classes CustomerGroup, Customer, Order et Item sont organisées dans une hiérarchie de compositions. Nous souhaitons tout d abord afficher les informations d un groupe de clients (classes CustomerGroup et Customer) passant des commandes (classe Order) comprenant plusieurs articles (Item). Le traitement spécifique effectué dans cette première visite est spécifié dans la classe ContentVisitor. Ensuite, nous souhaitons parcourir de la même manière les collections imbriquées pour calculer le chiffre d affaire total, ce chiffre d affaire étant calculé à partir du prix de chaque article (attribut price de la classe Item) et des remises appliquées selon le client (attribut reductionrate de la classe Customer). Cette seconde visite est spécifiée dans la classe BusinessVisitor. Le fonctionnement du patron de conception «Visiteur» est le suivant. Le patron de conception «Visiteur» appelle la méthode accept sur l objet racine des collections imbriquées. La méthode accept de l objet racine appelle une méthode de même nom (accept) sur les références des objets de la collection qu il gère. La méthode accept des objets de cette collection appelle à son tour une méthode accept sur les objets des collections qu ils possèdent, etc. Ainsi, toutes les collections sont parcourues pour construire un graphe d appels de méthodes accept. C est la première fonctionnalité du patron de conception «Visiteur» : parcourir les éléments des collections imbriquées. La seconde fonctionnalité est la suivante. Lorsqu un nœud de l arbre est visité, en plus des appels accept sur les objets enfants accessibles à partir de ce nœud, la méthode accept effectue un traitement local. Ce traitement est effectué en appelant une méthode visit d une classe appelée «visiteur» qui réalise les traitements. Par conséquent, la classe jouant le rôle d un visiteur contient des méthodes visit, une méthode par type d objets visités. Présentation de la modélisation disponible pour l implantation. Voici quelques détails sur le diagramme de classes : interface Visitor : déclare les méthodes appelables lors des visites (des parcours d une collection), une méthode pour chaque type d objets de collection visités ; classe ContentReport et BusinessReport : exemples de visiteurs des collections. Chaque méthode visit définit ce qu il faut faire lorsqu un objet est parcouru lors de la visite. Par exemple, en ce qui concerne la classe ContentReport, le type et le nom de l objet sont affichés à l écran puis un compteur par classe d objets est incrémenté (customernb, ordersnb et itemsnb pour respectivement Customer, Order et Item). La dernière méthode displayresults affiche les compteurs. Cette méthode est généralement appelée après les visites. Le contenu de cette classe est donné dans la figure 2. interface Visitable : déclare la méthode accept utilisée lors des visites. Dans les collections feuilles de l arborescence (par exemple, la classe Item), cette méthode appelle la méthode visit du visiteur. Dans les autres collections (par exemple, la classe Order), elle parcourt en plus les «sous-collections» et appelle la méthode accept sur chacun des objets des sous-collections ; classes CustomerGroup, Customer, Order et Item : exemples de classes «visitables» dont la méthode accept est appelée lorsqu un objet de la classe est visité lors du parcours de la collection dans laquelle il est inséré. Nous donnons le corps de la méthode accept ci-dessous pour la classe Customer. Remarquez que la référence sur le visiteur est un argument de la méthode. Cela permet d appeler la méthode visit correspondante du visiteur pour le traitement à effectuer lors de la visite, par exemple de mettre à jour les statistiques dans le visiteur ContentReport. Télécom SudParis Denis Conan et Christian Bac Mardi 25 janvier 2011 CSC4102 2

public void accept(visitor visitor) { visitor.visit(this); for (Iterator<Order> it = orders.iterator(); it.hasnext();) { ((Visitable) it.next()).accept(visitor); classe CustomerGroup : contient la racine de l arborescence des collections. Dans notre exemple, ce sont tous les objets de classe Customer. La classe CustomerGroup contient aussi une méthode accept dont le corps de la méthode est le suivant : public void accept(visitor visitor) { for (Iterator<Customer> it = customers.iterator(); it.hasnext();) { ((Customer) it.next()).accept(visitor); Enfin, la figure 3 présente le diagramme de communications d une méthode main d une classe Main montrant un cas d utilisation du système. Ce diagramme de communications n est pas complet : le message «21» donne lieu a des traitements imbriqués. La figure 4 présente le début du traitement de ce message. Ce n est que le début dans le sens où la figure présente la visite jusqu au premier objet feuille (de l objet cg:customergroup à l objet ia:item en passant par les objets c2:customer et o2:order), sans la visite des autres objets de types Customer, Order et Item. Télécom SudParis Denis Conan et Christian Bac Mardi 25 janvier 2011 CSC4102 3

visitor BusinessReport totalamount:double customervisited:customer +visit(customer):void +visit(order):void +visit(item):void +gettotalamount():double <<interface>> Visitor +visit(customer):void +visit(order):void +visit(item):void ContentReport customersnb:int ordersnb:int itemsnb:int +visit(customer):void +visit(order):void +visit(item):void +displayresults():void CustomerGroup +constructeur() +addcustomer(customer):void +accept(visitor):void <<interface>> Visitable +accept(visitor):void Item name:string price:double +constructeur(string,double) +getname():string +getprice():double +accept(visitor):void * * Customer Order name:string discountrate:double +constructeur(string,double) +getname():string +getdiscountrate():double +addorder(order):void +accept(visitor):void * name:string +constructeur(string) +constructeur(string,string,double) +getname():string +additem(item):void +accept(visitor):void Figure 1 Diagramme de classes Télécom SudParis Denis Conan et Christian Bac Mardi 25 janvier 2011 CSC4102 4

p u b l i c c l a s s ContentReport implements V i s i t o r { p r i v a t e i n t customersno ; p r i v a t e i n t ordersno ; p r i v a t e i n t itemsno ; p u b l i c void v i s i t ( Customer customer ) { System. out. p r i n t l n ( customer. getname ( ) ) ; customersno++; p u b l i c void v i s i t ( Order order ) { System. out. p r i n t l n ( order. getname ( ) ) ; ordersno++; p u b l i c void v i s i t ( Item item ) { System. out. p r i n t l n ( item. getname ( ) ) ; itemsno++; p u b l i c void d i s p l a y R e s u l t s ( ) { System. out. p r i n t l n ( "Nb o f customers : " + customersno ) ; System. out. p r i n t l n ( "Nb o f o r d e r s : " + ordersno ) ; System. out. p r i n t l n ( "Nb o f i t e m s s : " + itemsno ) ; Figure 2 Code Java de la classe ContentReport Télécom SudParis Denis Conan et Christian Bac Mardi 25 janvier 2011 CSC4102 5

20 create() 22 displayresults() 17 create() 18 addcustomer(c1) 19 addcustomer(c2) 21 cr:contentreport cg:customergroup 15 create("customer2",0.2) 16 addorder(o4) 11 create("order4") 12 additem(ia) 13 additem(ib) 14 additem(ic) c2:customer o4:order 10 create("itema",4) ia:item 9 create("itemb",5) ib:item 8 create("itemc",6) ic:item Main 5 addorder(o1) 6 addorder(o2) 7 addorder(o3) 1 create("customer1",0.1) c1:customer 2 create("order1","item1",1) o1:order 2.1 create("item1",1) i1:item 3 create("order2","item2",2) o2:order 3.1 create("item2",2) i2:item 4 create("order3","item3",3) o3:order 4.1 create("item3",3) i3:item Figure 3 Diagramme de communications de la méthode main de la classe Main Télécom SudParis Denis Conan et Christian Bac Mardi 25 janvier 2011 CSC4102 6

cr:contentreport 21.1.2.2.1 visit(ia) 21.1.2.1 visit(o4) 21.1.1 visit(c2) o4:order ia:item 21 cg:customergroup c2:customer 21.1.2 21.1 21.1.1.1 getname() 21.1.2.2 21.1.2.1.1 getname() 21.1.2.2.1.1 getname() ib:item ic:item 21.1.2.3 21.1.2.4 c1:customer 21.2 o1:order i1:item o2:order i2:item o3:order i3:item Figure 4 Début de la fin du diagramme de communications de la figure 3 à partir du message «21». Ce n est que le début du traitement car la figure présente la visite jusqu au premier objet feuille (de l objet cg:customergroup à l objet ia:item en passant par les objets c2:customer et o2:order) sans la visite des autres objets de types Customer, Order et Item. Les flèches en pointillées montre la suite des interactions à ajouter pour terminer le diagramme. C est clairement une entorse à la notation UML, mais nous désirons uniquement montrer le principe de la visite et souhaitons que le diagramme ne soit pas trop chargé. Télécom SudParis Denis Conan et Christian Bac Mardi 25 janvier 2011 CSC4102 7

2 Programmation Voici le code de l interface Visitable. p u b l i c i n t e r f a c e V i s i t a b l e { p u b l i c void accept ( V i s i t o r v i s i t o r ) ; Voici le code de la classe Order. import java. s q l. R esultset ; import java. s q l. SQLException ; import java. s q l. Statement ; import java. u t i l. I t e r a t o r ; import java. u t i l. Vector ; p u b l i c c l a s s Order implements V i s i t a b l e { p r i v a t e S t r i n g name ; p r i v a t e Vector<Item> items = new Vector<Item >(); p u b l i c Order ( S t r i n g n ) { name = n ; items = new Vector<Item >(); p u b l i c Order ( S t r i n g n, S t r i n g itemname, double itemprice ) { name = n ; items = new Vector<Item >(); additem ( new Item ( itemname, itemprice ) ) ; p u b l i c S t r i n g getname ( ) { r e t u r n name ; p u b l i c void accept ( V i s i t o r v i s i t o r ) { v i s i t o r. v i s i t ( t h i s ) ; f o r ( I t e r a t o r <Item> i t = items. i t e r a t o r ( ) ; i t. hasnext ( ) ; ) { ( ( Item ) i t. next ( ) ). accept ( v i s i t o r ) ; p u b l i c void additem ( Item item ) { items. add ( item ) ; // code pour l a reponse a l a q u e s t i o n 9 p u b l i c void initfromdb ( Statement stmt ) throws OperationImpossible { S t r i n g query = " s e l e c t from order where name = " + name + " " ; t r y { ResultSet r s e t = stmt. executequery ( query ) ; i n t order_idx ; i f ( r s e t. f i r s t ( ) ) { order_idx = r s e t. g e t I n t ( " idx " ) ; e l s e { throw new OperationImpossible ( " Order not found i n DB " + query ) query = " s e l e c t from item where order_id = " + order_idx + " " ; r s e t = stmt. executequery ( query ) ; while ( r s e t. next ( ) ) { S t r i n g n = r s e t. g e t S t r i n g ( " name " ) ; double p = r s e t. getdouble ( " p r i c e " ) ; additem ( new Item (n, p ) ) ; catch ( SQLException se ) { throw new OperationImpossible ( " Echec a c c e s Items " ) ; Télécom SudParis Denis Conan et Christian Bac Mardi 25 janvier 2011 CSC4102 8

Voici la méthode main de la classe Main, y compris son prototype. package eu. t e l e c o m s u d p a r i s. csc4102. d e s i g n p a t t e r n. v i s i t o r ; import eu. t e l e c o m s u d p a r i s. csc4102. d e s i g n p a t t e r n. v i s i t o r. g e s t i o n d e c l i e n t s. ContentReport ; import eu. t e l e c o m s u d p a r i s. csc4102. d e s i g n p a t t e r n. v i s i t o r. g e s t i o n d e c l i e n t s. Customer ; import eu. t e l e c o m s u d p a r i s. csc4102. d e s i g n p a t t e r n. v i s i t o r. g e s t i o n d e c l i e n t s. CustomerGroup ; import eu. t e l e c o m s u d p a r i s. csc4102. d e s i g n p a t t e r n. v i s i t o r. g e s t i o n d e c l i e n t s. Item ; import eu. t e l e c o m s u d p a r i s. csc4102. d e s i g n p a t t e r n. v i s i t o r. g e s t i o n d e c l i e n t s. Order ; p u b l i c c l a s s Main { p u b l i c s t a t i c void main ( S t r i n g [ ] a r g s ) { Customer c = new Customer ( " customer1 ", 0. 1 ) ; c. addorder ( new Order ( " order1 ", " item1 ", 1 ) ) ; c. addorder ( new Order ( " order2 ", " item2 ", 2 ) ) ; c. addorder ( new Order ( " order3 ", " item3 ", 3 ) ) ; Customer c2 = new Customer ( " customer2 ", 0. 2 ) ; Order o = new Order ( " order4 " ) ; o. additem ( new Item ( " itema ", 4 ) ) ; o. additem ( new Item ( " itemb ", 5 ) ) ; o. additem ( new Item ( " itemc ", 6 ) ) ; c2. addorder ( o ) ; CustomerGroup customers = new CustomerGroup ( ) ; customers. addcustomer ( c ) ; customers. addcustomer ( c2 ) ; ContentReport v i s i t o r = new ContentReport ( ) ; customers. accept ( v i s i t o r ) ; v i s i t o r. d i s p l a y R e s u l t s ( ) ; Nous écrivons maintenant le constructeur de la classe Item pour qu il lève une exception lorsque l un des attributs n est pas renseigné. Nous supposons que nous avons à notre disposition la classe d exception OperationImpossible (telle qu elle est implantée dans le cas d étude «Médiathèque»). p u b l i c c l a s s ItemWithException { p r i v a t e S t r i n g name ; p r i v a t e double p r i c e ; p u b l i c ItemWithException ( S t r i n g n, double p ) throws OperationImpossible { i f ( ( name == n u l l ) ( p r i c e == 0 ) ) { throw new OperationImpossible ( "Un des arguments n e s t pas r e n s e i g n e " ) ; name = n ; p r i c e = p ; Nous écrivons maintenant un test permettant de tester que le constructeur de la classe Item lève une exception lorsque l un des attributs n est pas renseigné. import org. j u n i t. Test ; p u b l i c c l a s s JUnit_ItemWithExceptionTest { @Test ( expected=operationimpossible. c l a s s ) p u b l i c void testnotnullname ( ) throws OperationImpossible { new ItemWithException ( n u ll, 1. 0 ) ; Télécom SudParis Denis Conan et Christian Bac Mardi 25 janvier 2011 CSC4102 9

Le second visiteur, c est-à-dire la classe BusinessReport, sert à calculer le chiffre d affaire total selon la formule qui suit. Nous écrivons tout le code Java de la classe BusinessReport. ( ( )) totalamount = (i.getp rice() (1 c.getdiscountrate())) c Customer o Order i Item p u b l i c c l a s s BusinessReport implements V i s i t o r { p r i v a t e double totalamount ; p r i v a t e Customer c u s t o m e r V i s i ted ; p u b l i c BusinessReport ( ) { totalamount = 0 ; c u s t o m e r V i s i t e d = n u l l ; p u b l i c void v i s i t ( Customer customer ) { c u s t o m e r V i s i t e d = customer ; p u b l i c void v i s i t ( Order order ) { p u b l i c void v i s i t ( Item item ) { totalamount += item. g e t P r i c e ( ) (1 customervisited. getdiscountrate ( ) ) ; p u b l i c double gettotalamount ( ) { r e t u r n totalamount ; Télécom SudParis Denis Conan et Christian Bac Mardi 25 janvier 2011 CSC4102 10