Java Design Patterns
Java Design Patterns
Un design pattern ou pattern de conception consiste en un schma objets qui forme une solution un problme [Link] liantlesobjets. [Link] sont des solutions connues et prouves dont la conception provient de lexprience de programmeurs. Il ny a pas daspectthoriquedanslespatterns,notammentpasdeformalisation(ladiffrencedesalgorithmes). [Link],lafigure1.1donne lexemple du pattern Template method qui sera dcrit au chapitre Le pattern Template Method. Dans ce pattern, la mthode calculeMontantTtcinvoquelamthode calculeTvaquiestabstraitedanslaclasse [Link] danslessousclassesde Commandesavoirlesclasses CommandeFranceet [Link],letauxdeTVA varie en fonction du pays. La mthode calculeMontantTtc est appele mthode "patron" ( Template method). Elle introduitunalgorithmebassurunemthodeabstraite. Cepatternestbassurlepolymorphisme,[Link] [Link],lecalculdeTVAestdonc [Link],lepatternTemplate methodconstitueunebonneillustrationdu polymorphisme.
Figure1.1ExempledutilisationdupatternTemplateMethod Lespatternsonttintroduitsen1995danslelivredit"GoF"pourGangofFour(quisontlesquatreauteurs)intitul "Design Patterns Elements of Reusable ObjectOriented Software" et crit par Erich Gamma, Richard Helm, Ralph [Link].
- 1-
Ladescriptiondespatternsdeconception
Nousavonsfaitlechoixdedcrirelespatternsdeconceptionlaidedesdeuxlangagessuivants :
q
lelangagedemodlisationUMLintroduitparlOMG([Link] lelangagedeprogrammationJavacrparlasocit"SunMicrosystems"([Link]
Les patterns de conception sont introduits dans les parties 2 4. Pour chaque pattern, les lments suivants sont prsents :
q
lesdomainesdapplicationdupattern lexemple prsent cette fois sous la forme dun programme Java complet et document. Ce programme nutilisepasdinterfacegraphiquemaisexclusivementlesentres/sortiesdelcranetduclavier.
- 1-
Lecataloguedespatternsdeconception
Danscelivrenousprsentonslesvingttroispatternsdeconceptionintroduitsdanslouvragederfrence"GoF".Ces [Link] nestpasexhaustive,elleprovientcommenouslavonsdjexpliqudelexprience.
q
AbstractFactory : apourobjectiflacrationdobjetsregroupsenfamillessansdevoirconnatrelesclasses concrtesdestineslacrationdecesobjets Builder : permet de sparer la construction dobjets complexes de leur implantation de sorte quun client puissecrercesobjetscomplexesavecdesimplantationsdiffrentes FactoryMethod : apourbutdintroduireunemthodeabstraitedecrationdunobjetenreportantauxsous classesconcrteslacrationeffective Prototype : permet la cration de nouveaux objets par duplication dobjets existants appels prototypes qui disposentdelacapacitdeclonage Singleton : permet de sassurer quune classe ne possde quune seule instance et de fournir une mthode uniqueretournantcetteinstance Adapter : a pour but de convertir linterface dune classe existante en linterface attendue par des clients galementexistantsafinquilspuissenttravaillerensemble Bridge : apourbutdesparerlesaspectsconceptuelsdunehirarchiedeclassesdeleurimplantation Composite : offre un cadre de conception dune composition dobjets dont la profondeur de composition est variable,laconceptiontantbasesurunarbre Decorator : permetdajouterdynamiquementdesfonctionnalitssupplmentairesunobjet Facade : a pour but de regrouper les interfaces dun ensemble dobjets en une interface unifie rendant cet ensembleplussimpleutiliser Flyweight : facilitelepartagedunensembleimportantdobjetsdontlegrainestfin Proxy : construitunobjetquisesubstitueunautreobjetetquicontrlesonaccs Chain of responsibility : creunechanedobjets telle que si un objet de la chane ne peut pas rpondre unerequte,ilpuisselatransmettresessuccesseursjusqucequelundentreeuxyrponde Command : a pour objectif de transformer une requte en un objet, facilitant des oprations comme lannulation,lamiseenfiledesrequtesetleursuivi Interpreter : fournit un cadre pour donner une reprsentation par objets de la grammaire dun langage afin dvaluer,enlesinterprtant,desexpressionscritesdanscelangage Iterator : fournit un accs squentiel une collection dobjets sans que les clients se proccupent de limplantationdecettecollection Mediator : construit un objet dont la vocation est la gestion et le contrle des interactions au sein dun ensembledobjetssansqueseslmentsseconnaissentmutuellement Memento : sauvegardeetrestaureltatdunobjet Observer : construit une dpendance entre un sujet et des observateurs de faon ce que chaque modificationdusujetsoitnotifieauxobservateursafinquilspuissentmettrejourleurtat
- 1-
State : permetunobjetdadaptersoncomportementenfonctiondesontatinterne Strategy : adapte le comportement et les algorithmes dun objet en fonction dun besoin sans changer les interactionsaveclesclientsdecetobjet TemplateMethod : permetdereporterdansdessousclassescertainestapesdelunedesoprationsdun objet,cestapestantalorsdcritesdanslessousclasses Visitor : construituneoprationralisersurleslmentsdun ensemble [Link] peuventainsitreajoutessansmodifierlesclassesdecesobjets.
- 2-
tudierdefaonapprofondiesastructuregnriquequisertdebasepourutiliserunpattern renommer les classes et les mthodes introduites dans la structure gnrique. En effet, dans la structure gnriquedunpattern,[Link],unefoisintgresdans une application, ces classes et mthodes doivent tre respectivement nommes relativement aux objets [Link] utiliserunpattern adapter la structure gnrique pour rpondre aux contraintes de lapplication, ce qui peut impliquer des changementsdansleschmadobjets.
Figure1.2StructuregnriquedupatternTemplateMethod NousvoulonsadaptercettestructuredanslecadreduneapplicationdecommerceolamthodeducalculdelaTVA nestpasinclusedanslaclasse [Link] classescontiennenttouteslesmthodesdecalculdestaxesspcifiqueschaquepays. La mthode calculeTVA de la classe Commande va alors invoquer la mthode calculeTVA de la sousclasse du pays [Link] crationdelacommande. Lepatternadaptprtlutilisationdanslapplicationestillustrlafigure1.3.
- 1-
Figure1.3ExempledutilisationavecadaptationdupatternTemplateMethod
- 2-
Organisationducataloguedespatternsdeconception
Pour organiser le catalogue des patterns de conception, nous reprenons la classification du "GoF" qui organise les patternsselonleurvocation :construction,structurationetcomportement. [Link] nombredecinq :AbstractFactory,Builder,FactoryMethod,PrototypeetSingleton. [Link] [Link] :Adapter,Bridge,Composite,Decorator,Facade,FlyweightetProxy. Enfin, les patterns de comportement proposent des solutions pour organiser les interactions et pour rpartir les traitements entre les objets. Ils sont dcrits dans la partie 4. Ils sont au nombre de onze : Chain of responsibility, Command,Interpreter,Iterator,Mediator,Memento,Observer,State,Strategy,TemplateMethodetVisitor.
- 1-
Descriptiondusystme
Dans cet ouvrage, nous prenons lexemple de la conception dun systme pour illustrer la mise en uvre des vingt troispatternsdeconception. Lesystmeconcevoirestunsitewebdeventeenlignedevhiculescomme,parexemple,desautomobilesoudes scooters. Ce systme autorise diffrentes oprations comme laffichage dun catalogue, la prise de commande, la [Link].
- 1-
Cahierdescharges
Le site permet dafficher un catalogue de vhicules proposs la vente, deffectuer des recherches au sein de ce catalogue,depassercommandedunvhicule,dechoisirdesoptionspourceluiciavecunsystmedechariotvirtuel. Lesoptionsincompatiblesentreellesdoiventgalementtregres(parexemple"sigessportifs"et"sigesencuir" sontdesoptionsincompatibles).Ilestgalementpossibledereveniruntatprcdentduchariot. Le systme doit grer les commandes. Il doit tre capable de calculer les taxes en fonction du pays de livraison du [Link] [Link] :encours,valideetlivre. Lors de la commande dun vhicule, le systme construit la liasse des documents ncessaires comme la demande dimmatriculation,[Link] formatHTML. Lesystmepermetgalementdesolderlesvhiculesdifficilesvendre,savoirceuxquisontdanslestockdepuis longtemps. Ilpermetgalementunegestiondesclients,enparticulierdessocitspossdantdesfilialesafindeleurproposer, parexemple,lachatduneflottedevhicules. Lorsdelavisualisationducatalogue,[Link] peuttreprsentavecunoutroisvhiculesparligne. Larecherchedanslecataloguepeutseffectuerlaidedemotsclsetdoprateurslogiques(et,ou). Ilestpossibledaccderausystmeviauneinterfacewebclassiqueouautraversdunsystmedewebservices.
- 1-
Priseencomptedespatternsdeconception
Afin de raliser les diffrentes contraintes exprimes dans le cahier des charges, nous utilisons dans les chapitres [Link] web : Descriptiondelapartie Construirelesobjetsdudomaine (Automobile essence,automobilelectricit,etc.). Construirelesliassesdedocumentsncessairesen casdacquisitiondunvhicule. Crerlescommandes. Crerlaliasseviergededocuments. GrerdesdocumentsPDF. ImplanterdesformulairesenHTMLoulaidedune applet. Reprsenterlessocitsclientes. Afficherlesvhiculesducatalogue. Fournirlinterfaceenservicewebdusite. Grerlesoptionsdunvhiculecommand. Grerlaffichagedanimationspourchaquevhiculedu catalogue. Grerladescriptiondunvhicule. Solderlesvhiculesrestsenstockpendantune longuedure. Rechercherdanslabasedevhiculeslaidedune requtecritesouslaformeduneexpressionlogique. Retrouversquentiellementlesvhiculesdu catalogue. Grerleformulairedunedemandedecrdit. Grerlestatsdunecommande. Calculerlemontantdunecommande. Envoyerdespropositionscommercialesparemail certainessocitsclientes. Patterndeconception AbstractFactory
Builder,Prototype FactoryMethod Singleton Adapter Bridge Composite Decorator,Observer,Strategy Facade Flyweight,Memento Proxy Chainofresponsibility Command
Interpreter
- 1-
Prsentation
[Link] ces patterns devient indpendant de la faon dont les objets sont crs et, en particulier, des mcanismes dinstanciationdesclassesconcrtes. Ces patterns encapsulent lutilisation des classes concrtes et favorisent ainsi lutilisation des interfaces dans les relationsentreobjets,augmentantlescapacitsdabstractiondanslaconceptionglobaledusystme. Ainsi,[Link] [Link] cetteclasse.
- 1-
Lesproblmeslislacrationdobjets
[Link]
Danslaplupartdeslangagesobjets,lacrationdobjetssefaitgrceaumcanismedinstanciationquiconsiste crerunnouvelobjetparappeldeloprateur newparamtrparuneclasse(etventuellementdesargumentsdu constructeur de la classe dont le but est de donner aux attributs leur valeur initiale). Un tel objet est donc une instancedecetteclasse. LeslangageslesplusutilissaujourdhuicommeJava,C++ouC#utilisentlemcanismedeloprateurnew. EnJava,uneinstructiondecrationdunobjetpeutscrireainsi : objet = new Classe(); Dans certains cas, il est ncessaire de paramtrer la cration dobjets. Prenons lexemple dune mthode [Link],[Link] dudocumentcreresttransmisenparamtrelamthodesousformedunechanedecaractres,cequidonnele codesuivant : public Document construitDoc(String typeDoc) { Document rsultat; if ([Link]("PDF")) rsultat = new DocumentPDF(); else if ([Link]("RTF")) rsultat = new DocumentRTF(); else if ([Link]("HTML")) rsultat = new DocumentHTML(); // suite de la mthode } Cetexemplenousmontrequilestdifficiledeparamtrerlemcanismedecrationdobjets,laclassetransmiseen paramtre loprateur new ne pouvant tre substitue par une variable. Lutilisation dinstructionsconditionnelles dans le code du client est souvent pratique avec linconvnient que chaque changement dans la hirarchie des [Link],ilfautchangerlecode delamthodeconstruitDocencasdajoutdenouvellesclassesdedocument. Nanmoins, certains langages offrent des mcanismes plus ou moins souples et souvent assez complexes pour crer des instances partir du nom dune classe contenu dans une variable de type String.
Ladifficultestencoreplusgrandequandilfautconstruiredesobjetscompossdontlescomposantspeuventtre [Link],uneliassededocumentspeuttreformededocumentsPDF, RTF ou HTML. Le client doit alors connatre toutes les classes possibles des composants et des composs. Chaque modificationdanscesensemblesdeclassesdevientalorstrslourdegrer.
[Link]
Les patterns Abstract Factory, Builder, Factory Method et Prototype proposent une solution pour paramtrer la cration dobjets. Dans le cas des patterns Abstract Factory, Builder et Prototype, un objet est utilis comme [Link] desclassesnentranequedeschangementsdanslamodificationdecetobjet. LepatternFactory [Link] implantent la cration des objets. Tout changement dans la hirarchie des classes entrane par consquent une modificationdelahirarchiedessousclassesdelaclassecliente.
- 1-
Description
Le but du pattern Abstract Factory est la cration dobjets regroups en familles sans devoir connatre les classes concrtesdestineslacrationdecesobjets.
- 1-
Exemple
Le systme de vente de vhicules gre des vhicules fonctionnant lessence et des vhicules fonctionnant [Link]. Pourchaqueproduit,nousdisposonsduneclasseabstraite,dunesousclasseconcrtedcrivantlaversionduproduit [Link], la figure 4.1, pour lobjet scooter, il existe une classe abstraite Scooter et deux sousclasses concrtes ScooterlectricitetScooterEssence. Lobjet [Link],parlasuite,de nouvelles familles de vhicules doivent tre prises en compte par la suite (diesel ou mixte essencelectricit), les modificationsapporterlobjetCataloguepeuventtreassezlourdes. Le pattern Abstract Factory rsout ce problme en introduisant une interface FabriqueVhicule qui contient la [Link] [Link] Cataloguenapasbesoindeconnatrelessousclassesconcrtesetreste indpendantdesfamillesdeproduit. Unesousclasse dimplantationde FabriqueVhiculeestintroduitepourchaquefamilledeproduit,savoirlessous classes FabriqueVhiculelectricit et .FabriqueVhiculeEssence. Une telle sousclasse implante les oprations de crationduvhiculeappropriepourlafamillelaquelleelleestassocie. Lobjet CatalogueprendalorspourparamtreuneinstancerpondantlinterfaceFabriqueVhicule,cestdiresoit uneinstancedeFabriqueVhiculelectricit,[Link], le catalogue peut crer et manipuler des vhicules sans devoir connatre les familles de vhicule et les classes concrtesdinstanciationcorrespondantes. LensembledesclassesdupatternAbstract Factorypourcetexempleestdtailllafigure4.1.
- 1-
Figure4.1LepatternAbstract Factoryappliqudesfamillesdevhicules
- 2-
Structure
[Link]
Lafigure4.2dtaillelastructuregnriquedupattern.
Figure4.2StructuredupatternAbstract Factory
[Link]
Lesparticipantsaupatternsontlessuivants :
q
FabriqueAbstraite (FabriqueVhicule) est une interface spcifiant les signatures des mthodes crant les diffrentsproduits
- 1-
FabriqueConcrte1, FabriqueConcrte2 (FabriqueVhiculelectricit, FabriqueVhiculeEssence) sont les [Link] familleetleproduit,ellessontcapablesdecreruneinstanceduproduitpourcettefamille ProduitAbstraitAet ProduitAbstraitB (Scooter et Automobile) sont les classes abstraites des produits [Link] ClientestlaclassequiutiliselinterfacedeFabriqueAbstraite.
[Link]
LaclasseClientutiliseuneinstancedelunedesfabriquesconcrtespourcrersesproduitsautraversdelinterface deFabriqueAbstraite. Normalement, il ne faut crer quune seule instance des fabriques concrtes, celleci pouvant tre partageparplusieursclients.
- 2-
Domainesdutilisation
Lepatternestutilisdanslesdomainessuivants :
q
Un systme utilisant des produits a besoin dtre indpendant de la faon dont ces produits sont crs et regroups Unsystmeestparamtrparplusieursfamillesdeproduitsquipeuventvoluer.
- 1-
ExempleenJava
[Link] [Link],dcritlesquatreattributsdes automobilesainsiquelamthodeafficheCaractristiquequipermetdelesafficher. public abstract class Automobile { protected String modle; protected String couleur; protected int puissance; protected double espace; public Automobile(String modle, String couleur, int puissance, double espace) { [Link] = modle; [Link] = couleur; [Link] = puissance; [Link] = espace; } public abstract void afficheCaractristiques(); } public class Automobilelectricit extends Automobile { public Automobilelectricit(String modle, String couleur, int puissance, double espace) { super(modle,couleur,puissance,espace); } public void afficheCaractristiques() { [Link]("Automobile lectrique de modle : "+modle+ " de couleur : "+couleur+" de puissance : "+puissance+ " despace : "+espace); } }
public class AutomobileEssence extends Automobile { public AutomobileEssence(String modle, String couleur, int puissance, double espace) { super(modle,couleur,puissance,espace); } public void afficheCaractristiques() { [Link]("Automobile essence de modle : "+modle+ " de couleur : "+couleur+" de puissance : "+puissance+ " despace : "+espace); } } [Link] desautomobiles,lexceptiondelattributespacequinexistepaspourlesscooters. public abstract class Scooter { protected String modle; protected String couleur; protected int puissance;
- 1-
public Scooter(String modle, String couleur, int puissance) { [Link] = modle; [Link] = couleur; [Link] = puissance; } public abstract void afficheCaractristiques(); }
public class Scooterlectricit extends Scooter { public Scooterlectricit(String modle, String couleur, int puissance) { super(modle, couleur, puissance); } public void afficheCaractristiques() { [Link]("Scooter lectrique de modle : "+modle+ " de couleur : "+couleur+" de puissance : "+puissance); } }
public class ScooterEssence extends Scooter { public ScooterEssence(String modle, String couleur, int puissance) { super(modle, couleur, puissance); } public void afficheCaractristiques() { [Link]("Scooter essence de modle : "+modle+ " de couleur : "+couleur+" de puissance : "+puissance); } } Nouspouvonsmaintenantintroduirelinterface FabriqueVhiculeetsesdeuxclassesdimplantation,unepourchaque famille(lectricit/essence).Ilestaisdevoirqueseuleslesclassesdimplantationutilisentlesclassesconcrtesdes vhicules. public interface FabriqueVhicule { Automobile creAutomobile(String modle, String couleur, int puissance, double espace); Scooter creScooter(String modle, String couleur, int puissance); }
public class FabriqueVhiculelectricit implements FabriqueVhicule { public Automobile creAutomobile(String modle, String couleur, int puissance, double espace) { return new Automobilelectricit(modle, couleur, puissance, espace);
- 2-
} public Scooter creScooter(String modle, String couleur, int puissance) { return new Scooterlectricit(modle, couleur, puissance); } }
public class FabriqueVhiculeEssence implements FabriqueVhicule { public Automobile creAutomobile(String modle, String couleur,int puissance, double espace) { return new AutomobileEssence(modle, couleur, puissance, espace); } public Scooter creScooter(String modle, String couleur, int puissance) { return new ScooterEssence(modle, couleur, puissance); } } Enfin,nousdonnonslecodesourceJavaduclientdelafabrique,savoirlecataloguequiest,dansnotreexemple,le [Link],ledbutdeceluiciconsistedemanderlafabriqueutiliser (lectricitouessence).Cettefabriquedevraitnormalementtrefournieenparamtreaucatalogue. Le reste du programme est totalement indpendant de la famille dobjets, respectant le but du pattern Abstract Factory. import [Link].*; public class Catalogue { public static int nbAutos=3; public static int nbScooters=2; public static void main(String[] args) { Scanner reader = new Scanner([Link]); FabriqueVhicule fabrique; Automobile[] autos = new Automobile[nbAutos]; Scooter[] scooters = new Scooter[nbScooters]; [Link]("Voulez-vous utiliser des vhicules lectriques"+" (1) ou essence (2) :"); String choix = [Link](); if ([Link]("1")) { fabrique = new FabriqueVhiculelectricit(); } else { fabrique = new FabriqueVhiculeEssence(); } for (int index=0;index<nbAutos;index++) autos[index] = [Link]("standard", "jaune", 6+index, 3.2); for (int index=0;index<nbScooters;index++) scooters[index] = [Link]("classic", "rouge", 2+index); for (Automobile auto: autos) [Link](); for (Scooter scooter: scooters) [Link](); } }
- 3-
Unexempledexcutionpourdesvhiculeslectricitestlesuivant : Voulez-vous utiliser des vhicules lectriques (1) ou essence (2) :1 Automobile lectrique de modle : standard de couleur : jaune de puissance : 6 despace : 3.2 Automobile lectrique de modle : standard de couleur : jaune de puissance : 7 despace : 3.2 Automobile lectrique de modle : standard de couleur : jaune de puissance : 8 despace : 3.2 Scooter lectrique de modle : classic de couleur : rouge de puissance : 2 Scooter lectrique de modle : classic de couleur : rouge de puissance : 3 Danscetexempledexcution,cestunefabriquedevhiculeslectriquesquiatcre,ainsilecatalogueconstruit desautomobilesetdesscooterslectriques.
- 4-
Description
Lebutdupattern Builderestdabstrairelaconstructiondobjetscomplexesdeleurimplantationdesortequunclient puissecrercesobjetscomplexessansdevoirseproccuperdesdiffrencesdimplantation.
- 1-
Exemple
Lorsdelachatdunvhicule,unvendeurcreuneliassededocumentscomprenantnotammentlebondecommande [Link] [Link],leclientluifournituneinstancedelaclasse CrateurLiasseVhiculeHtmlet,dans le second cas, une instance de la classe CrateurLiasseVhiculePdf. Le vendeur effectue ensuite la demande de crationdechaquedocumentdelaliassecetteinstance. Ainsi le vendeur cre les documents de la liasse laide des mthodes construitBonDeCommande et construitDemandeImmatriculation. Lensemble des classes du pattern Builder pour cet exemple est dtaill la figure 5.1. Cette figure montre la hirarchie des classes ConstructeurLiasseVhicule et Liasse. Le vendeur peut crer les bons de commande et les demandesdimmatriculationsansconnatrelessousclassesdeConstructeurLiasseVhiculenicellesdeLiasse. Lesrelationsdedpendanceentreleclientetlessousclassesde ConstructeurLiasseVhiculesexpliquentparlefait queleclientcreuneinstancedecessousclasses. La structure interne des sousclasses concrtes de Liasse nest pas montre (dont, par exemple, la relationdecompositionaveclaclasseDocument).
- 1-
Figure5.1LepatternBuilderappliqudesliassesdedocuments
- 2-
Structure
[Link]
Lafigure5.2dtaillelastructuregnriquedupattern.
Figure5.2StructuredupatternBuilder
[Link]
Lesparticipantsaupatternsontlessuivants :
q
ConstructeurAbstrait(ConstructeurLiasseVhicule)estlaclasseintroduisantlessignaturesdesmthodes construisant les diffrentes parties du produit ainsi que la signature de la mthode permettant dobtenirle produit,unefoisceluiciconstruit ConstructeurConcret (ConstructeurLiasseVhiculeHtmlet ConstructeurLiasseVhiculePdf) est la classe concrteimplantantlesmthodesduconstructeurabstrait Produit (Liasse) est la classe dfinissant le produit. Elle peut tre abstraite et possder plusieurs sous classesconcrtes( LiasseHtmletLiassePdf)encasdimplantationsdiffrentes
ENI Editions - All rigths reserved - Algeria Educ - 1-
Directeurestlaclassechargedeconstruireleproduitautraversdelinterfaceduconstructeurabstrait.
[Link]
[Link] constructeuretrenvoielersultatauclient.Lafigure5.3illustrecefonctionnementavecundiagrammedesquence UML.
Figure5.3DiagrammedesquencedupatternBuilder
- 2-
Domainesdutilisation
Lepatternestutilisdanslesdomainessuivants :
q
unclientabesoindeconstruiredesobjetscomplexessansconnatreleurimplantation unclientabesoindeconstruiredesobjetscomplexesayantplusieursreprsentationsouimplantations.
- 1-
ExempleenJava
Nous introduisons le petit exemple dutilisation du pattern crit en Java. Le code Java correspondant la classe abstraite [Link],lesdocumentssontdeschanes [Link] quireprsententlesdocuments. import [Link].*; public abstract class Liasse { protected List<String> contenu = new ArrayList<String>(); public abstract void ajouteDocument(String document); public abstract void imprime(); }
public class LiasseHtml extends Liasse { public void ajouteDocument(String document) { if ([Link]("<HTML>")) [Link](document); } public void imprime() { [Link]("Liasse HTML"); for (String s:contenu) [Link](s); } } public class LiassePdf extends Liasse { public void ajouteDocument(String document) { if ([Link]("<PDF>")) [Link](document); } public void imprime() { [Link]("Liasse PDF"); for (String s:contenu) [Link](s); } } Lecodesourcedesclassesquiconstruisentlesliassesestfournilasuite. public abstract class ConstructeurLiasseVhicule { protected Liasse liasse; public abstract void construitBonDeCommande(String nomClient); public abstract void construitDemandeImmatriculation (String nomDemandeur); public Liasse rsultat() { return liasse; } }
- 1-
public class ConstructeurLiasseVhiculeHtml extends ConstructeurLiasseVhicule { public ConstructeurLiasseVhiculeHtml() { liasse = new LiasseHtml(); } public void construitBonDeCommande(String nomClient) { String document; document = "<HTML>Bon de commande Client : "+nomClient+"</HTML>"; [Link](document); } public void construitDemandeImmatriculation(String nomDemandeur) { String document; document = "<HTML>Demande dimmatriculation Demandeur : "+nomDemandeur+"</HTML>"; [Link](document); } } public class ConstructeurLiasseVhiculePdf extends ConstructeurLiasseVhicule { public ConstructeurLiasseVhiculePdf() { liasse = new LiassePdf(); } public void construitBonDeCommande(String nomClient) { String document; document = "<PDF>Bon de commande Client : "+nomClient+"</PDF>"; [Link](document); } public void construitDemandeImmatriculation(String nomDemandeur) { String document; document = "<PDF>Demande dimmatriculation Demandeur : "+ nomDemandeur+"</PDF>"; [Link](document); } } La classe Vendeur est dcrite la suite. Son constructeur prend comme paramtre une instance de [Link] construitprendcommeparamtrelesinformations duclient,icilimitesaunomduclient. public class Vendeur { protected ConstructeurLiasseVhicule constructeur; public Vendeur(ConstructeurLiasseVhicule constructeur) { [Link] = constructeur; } public Liasse construit(String nomClient) { [Link](nomClient); [Link](nomClient);
- 2-
Liasse liasse = [Link](); return liasse; } } Enfin,nousdonnonslecodesourceJavaduclientduconstructeur,savoirlaclasse ClientVhiculequiconstituele programme principal. Le dbut de ce programme demande lutilisateur le constructeur utiliser qui est fourni au vendeur. import [Link].*; public class ClientVhicule { public static void main(String[] args) { Scanner reader = new Scanner([Link]); ConstructeurLiasseVhicule constructeur; [Link]("Voulez-vous construire des liasses HTML (1) ou "+ "PDF (2) :"); String choix = [Link](); if ([Link]("1")) { constructeur = new ConstructeurLiasseVhiculeHtml(); } else { constructeur = new ConstructeurLiasseVhiculePdf(); } Vendeur vendeur = new Vendeur(constructeur); Liasse liasse = [Link]("Martin"); [Link](); } } UnexempledexcutionpouruneliasseenPDFestlesuivant : Voulez-vous construire des liasses HTML (1) ou PDF (2) :2 Liasse PDF <PDF>Bon de commande Client : Martin</PDF> <PDF>Demande dimmatriculation Demandeur : Martin</PDF> Conformmentlademandeduclient,[Link] uneliasseHTML,lasortieestlasuivante : Voulez-vous construire des liasses HTML (1) ou PDF (2) :1 Liasse HTML <HTML>Bon de commande Client : Martin</HTML> <HTML>Demande dimmatriculation Demandeur : Martin</HTML>
- 3-
Description
LebutdupatternFactory Methodestdintroduireunemthodeabstraitedecrationdunobjetenreportantauxsous classesconcrteslacrationeffective.
- 1-
Exemple
Nous nous intressons aux clients et aux commandes. La classe Client introduit la mthode creCommande qui doit crer la commande. Certains clients commandent un vhicule en payant au comptant et dautres clients utilisent un crdit. En fonction de la nature du client, la mthode creCommande doit crer une instance de la classe CommandeComptant ou une instance de la classe CommandeCrdit. Pour raliser cette alternative, la mthode [Link] laclasseabstraiteClient :
q
la classe concrte ClientComptant dont la mthode creCommande cre une instance de la classe CommmandeComptant laclasseconcrteClientCrditdontlamthodecreCommandecreuneinstancedelaclasseCommmandeCrdit.
- 1-
Figure6.1LepatternFactory Methodappliqudesclientsetleurscommandes
- 2-
Structure
[Link]
Lafigure6.2dtaillelastructuregnriquedupattern.
Figure6.2StructuredupatternFactory Method
- 1-
[Link]
Lesparticipantsaupatternsontlessuivants :
q
CrateurAbstrait (Client) est une classe abstraite qui introduit la signature de la mthode de fabrique et limplantationdemthodesquiinvoquentlamthodedefabrique CrateurConcret (ClientComptant, ClientCrdit) est une classe concrte qui implante la mthode de [Link] Produit(Commande)estuneclasseabstraitedcrivantlespropritscommunesdesproduits ProduitConcret (CommandeComptant, CommandeCrdit) est une classe concrte dcrivant compltement un produit.
[Link]
Lesmthodesconcrtesdelaclasse CrateurAbstraitsebasentsurlimplantationdelamthodedefabriquedans [Link].
- 2-
Domainesdutilisation
Lepatternestutilisdanslescassuivants :
q
uneclasseneconnatquelesclassesabstraitesdesobjetsaveclesquelsellepossdedesrelations une classe veut transmettre ses sousclasses les choix dinstanciation en profitant du mcanisme de polymorphisme.
- 1-
ExempleenJava
Lecodesourcedelaclasseabstraite [Link] commande est pass en paramtre du constructeur de la classe. Si la validation dune commande au comptant est systmatique,nousavonslechoixpournotreexempledenaccepterquelescommandesassortiesduncrditdontla valeursesitueentre1000et5000. public abstract class Commande { protected double montant; Commande(double montant) { [Link] = montant; } public abstract boolean valide(); public abstract void paye(); }
public class CommandeComptant extends Commande { public CommandeComptant(double montant) { super(montant); } public void paye() { [Link]("Le paiement de la commande au comptant de : "+ montant+" est effectu."); } public boolean valide() { return true; } }
public class CommandeCrdit extends Commande { public CommandeCrdit(double montant) { super(montant); } public void paye() { [Link]("Le paiement de la commande au crdit de : "+ montant+" est effectu."); } public boolean valide() { return (montant >= 1000.0) && (montant <= 5000.0); } } [Link] passerplusieurscommandes,seulescellesquisontvalidessontajoutessaliste. import [Link].*; public abstract class Client {
- 1-
protected List<Commande> commandes = new ArrayList<Commande>(); protected abstract Commande creCommande(double montant); public void nouvelleCommande(double montant) { Commande commande = [Link](montant); if ([Link]()) { [Link](); [Link](commande); } } }
public class ClientComptant extends Client { protected Commande creCommande(double montant) { return new CommandeComptant(montant); } }
public class ClientCrdit extends Client { protected Commande creCommande(double montant) { return new CommandeCrdit(montant); } } Enfin,laclasseUtilisateurmontreunexempledemiseen uvredupatternFactory Method. LenomUtilisateurdnoteiciunobjetutilisateurdunpattern.
public class Utilisateur { public static void main(String[] args) { Client client; client = new ClientComptant(); [Link](2000.0); [Link](10000.0); client = new ClientCrdit(); [Link](2000.0); [Link](10000.0); } } Unexempledexcutiondelutilisateurdonnelasortiesuivante : Le paiement de la commande au comptant de : 2000.0 est effectu. Le paiement de la commande au comptant de : 10000.0 est effectu. Le paiement de la commande au crdit de : 2000.0 est effectu. Onpeutremarquerquelademandedunecommandeassortieduncrditde10000atrefuse.
- 2-
Description
Le but du pattern est la cration de nouveaux objets par duplication dobjets existants appels prototypes qui disposentdelacapacitdeclonage.
- 1-
Exemple
Lorsdelachatdunvhicule,unclientdoitrecevoiruneliassedfinieparunnombreprcisdedocumentstelsquele certificat de cession, la demande dimmatriculation ou encore le bon de commande. Dautres types de documents peuvent tre ajouts ou retirs cette liasse en fonction des besoins de gestion ou des changements de rglementation. Nous introduisons une classe Liasse dont les instances sont des liasses composes des diffrents [Link],nousintroduisonsuneclassecorrespondante. PuisnouscronsunmodledeliassequiestuneinstanceparticuliredelaclasseLiasseetquicontientlesdiffrents documents ncessaires, documents qui restent vierges. Nous appelons cette liasse, la liasse vierge. Ainsi nous dfinissons au niveau des instances le contenu prcis de la liasse que doit recevoir un client et non au niveau des [Link]. Unefoiscetteliasseviergeintroduite,[Link] liasseestcreendupliquanttouslesdocumentsdelaliassevierge. Cettetechniquebasesurdesobjetsdisposantdelacapacitdeclonageutiliselepattern Prototype,lesdocuments constituantlesdiffrentsprototypes. [Link] [Link] dupliquequipermetdecloner uneinstanceexistantepourenobtenirunenouvelle. [Link] :
q
la classe LiasseVierge qui ne possde quune seule instance, une liasse contenant tous les documents ncessaires(documentsvierges).Cetteinstanceestmanipuleautraversdesmthodesajouteetretire. Laclasse LiasseClientdontlensembledesdocumentsestcrendemandantluniqueinstancedelaclasse LiasseViergelalistedesdocumentsviergespuisenlesajoutantununaprslesavoirclons.
- 1-
Figure7.1LepatternPrototypeappliqulacrationdeliassedecontenuvariable
- 2-
Structure
[Link]
Lafigure7.2dtaillelastructuregnriquedupattern.
Figure7.2StructuredupatternPrototype
[Link]
ENI Editions - All rigths reserved - Algeria Educ - 1-
Lesparticipantsaupatternsontlessuivants :
q
Client (Liasse, LiasseClient, LiasseVierge) est une classe compose dun ensemble dobjets appels prototypes,instancesdelaclasseabstraite [Link] sansavoirconnatrenilastructureinternedePrototypenisahirarchiedesousclasses. Prototype(Document)[Link] signaturedelamthodeduplique. PrototypeConcret1et PrototypeConcret2 (BonDeCommande, DemandeImmatriculation, CertificatCession) sont les sousclasses concrtes de Prototype qui dfinissent compltement un prototype et en implante la mthodeduplique.
[Link]
Leclientdemandeunouplusieursprototypesdesedupliquereuxmmes.
- 2-
Domainesdutilisation
LepatternPrototypeestutilisdanslesdomainessuivants :
q
- 1-
ExempleenJava
[Link], ladiffrencedudiagrammedeclasses,lesmthodes dupliqueet remplitsontconcrtesdanslaclasse [Link] mthodedupliqueutiliselamthodeclonefournieparJava. public abstract class Document implements Cloneable { protected String contenu = new String(); public Document duplique() { Document resultat; try { resultat = (Document)[Link](); } catch(CloneNotSupportedException exception) { return null; } return resultat; } public void remplit(String informations) { contenu = informations; } public abstract void imprime(); public abstract void affiche(); }
public class BonDeCommande extends Document { public void affiche() { [Link]("Affiche le bon de commande : "+contenu); } public void imprime() { [Link]("Imprime le bon de commande : "+contenu); } }
public class DemandeImmatriculation extends Document { public void affiche() { [Link]("Affiche la demande dimmatriculation : "+ contenu); } public void imprime() { [Link]("Imprime la demande dimmatriculation : "+ contenu); } }
- 1-
{ [Link]("Affiche le certificat de cession : "+contenu); } public void imprime() { [Link]("Imprime le certificat de cession : "+contenu); } } LecodesourcedelaclasseabstraiteLiasseestlesuivant : import [Link].*; public abstract class Liasse { protected List<Document> documents; public List<Document> getDocuments() { return documents; } } [Link] Singletonqui estprsentdanslechapitresuivantetquiapourobjectifdassurerquuneclassenepossdequuneseuleinstance. import [Link].*; public class LiasseVierge extends Liasse { private static LiasseVierge _instance=null; private LiasseVierge() { documents = new ArrayList<Document>(); } public static LiasseVierge Instance() { if (_instance == null) _instance = new LiasseVierge(); return _instance; } public void ajoute(Document doc) { [Link](doc); } public void retire(Document doc) { int indexDoc = [Link](doc); if (indexDoc > 0) [Link](indexDoc); } } La sousclasse LiasseClient est crite en Java la suite. Son constructeur commence par obtenir la liste des documentsdelaliasseviergepuislesduplique,lesremplisetlesajouteununaucontenudelaliasse. import [Link].*; public class LiasseClient extends Liasse { public LiasseClient(String informations) { documents = new ArrayList<Document>(); LiasseVierge laLiasseVierge = [Link](); List<Document> documentsVierges =
- 2-
[Link](); for (Document document : documentsVierges) { Document copieDocument = [Link](); [Link](informations); [Link](copieDocument); } } public void affiche() { for (Document document : documents) [Link](); } public void imprime() { for (Document document : documents) [Link](); } } Enfin,nousdonnonslecodesourcedelaclasse Utilisateurdontlamthodemaincommenceparconstruirelaliasse viergeet,enparticulier,[Link]. public class Utilisateur { public static void main(String[] args) { // initialisation de la liasse vierge LiasseVierge liasseVierge = [Link](); [Link](new BonDeCommande()); [Link](new CertificatCession()); [Link](new DemandeImmatriculation()); // cration dune nouvelle liasse pour deux clients LiasseClient liasseClient1 = new LiasseClient("Martin"); LiasseClient liasseClient2 = new LiasseClient("Durant"); [Link](); [Link](); } } Lersultatdelexcutionestlesuivant : Affiche Affiche Affiche Affiche Affiche Affiche le le la le le la bon de commande : Martin certificat de cession : Martin demande dimmatriculation : Martin bon de commande : Durant certificat de cession : Durant demande dimmatriculation : Durant
- 3-
Description
LepatternSingletonapourbutdassurerquuneclassenepossdequuneseuleinstanceetdefournirunemthode declasseuniqueretournantcetteinstance. Danscertainscas,[Link] construction, nous pouvons citer le cas dune fabrique de produits (pattern Abstract Factory) dont il nest pas ncessairedecrerplusduneinstance.
- 1-
Exemple
Danslesystmedeventeenlignedevhicules,nousdevonsgrerdesclassespossdantuneseuleinstance. Lesystmedeliassededocumentsdestinsauclientlorsdelachatdunvhicule(commelecertificatdecession,la demande dimmatriculation et le bon de commande) utilise la classe LiasseVierge qui ne possde quune seule [Link] [Link] LiasseViergeest expliquedanslechapitreconsacraupatternPrototype. La figure 8.1 illustre lutilisation du pattern Singleton pour la classe LiasseVierge. Lattribut de classe instance [Link] [Link] null,ilestpralablementinitialis lorsdelacrationdeluniqueinstance.
Figure8.1LepatternSingletonappliqulaclasseLiasseVierge
- 1-
Structure
[Link]
Lafigure8.2dtaillelastructuregnriquedupattern.
Figure8.2StructuredupatternSingleton
[Link]
Leseulparticipantestlaclasse SingletonquioffrelaccsluniqueinstanceparsamthodedeclasseInstance. Par ailleurs, la classe Singleton possde un mcanisme qui assure quelle ne peut possder au plus quune seule [Link].
[Link]
Chaqueclientdelaclasse Singletonaccdeluniqueinstanceparlamthodedeclasse [Link] crerdenouvellesinstancesenutilisantloprateurhabitueldinstanciation(oprateurnew)quiestbloqu.
- 1-
Domainedutilisation
Lepatternestutilisdanslecassuivant :
q
- 1-
ExemplesenJava
[Link]
LecodeJavacompletdelaclasse LiasseViergeestdonndanslechapitredupattern [Link] classerelativelutilisationdupatternSingletonestfournielasuite. [Link],aucun objetexternelaclasseLiasseViergenepeutencrerdinstanceenutilisantloprateurnew. Delammefaon,lattribut _instancedtientgalementunevisibilitprivepourquelaccsnesoitpossibleque depuislamthodedeclasseInstance. import [Link].*; public class LiasseVierge extends Liasse { private static LiasseVierge _instance=null; private LiasseVierge() { documents = new ArrayList<Document>(); } public static LiasseVierge Instance() { if (_instance == null) _instance = new LiasseVierge(); return _instance; } ... } Leseulclientdelaclasse LiasseViergeestlaclasse LiasseClientqui,danssonconstructeur,obtientunerfrence [Link],leconstructeuraccdelalistedesdocumentsvierges. LiasseVierge laLiasseVierge = [Link](); List<Document> documentsVierges = [Link]();
[Link]
Danslesystmedeventedevhicules,nousvoulonsreprsenterlevendeurparuneclassepourymmoriserses informationspluttquedutiliserdesvariablesglobalesquivontrespectivementcontenirsonnom,sonadresse,etc. LaclasseVendeurestdcritecidessous. public class Vendeur { protected String nom; protected String adresse; protected String email; private static Vendeur _instance=null; private Vendeur() { } public static Vendeur Instance() { if (_instance == null) _instance = new Vendeur();
- 1-
return _instance; } public void affiche() { [Link]("Nom : "+nom); [Link]("Adresse : "+adresse); [Link]("Email : "+email); } public String getNom() { return nom; } public void setNom(String nom) { [Link] = nom; } public String getAdresse() { return adresse; } public void setAdresse(String adresse) { [Link] = adresse; } public String getEmail() { return email; } public void setEmail(String email) { [Link] = email; } } LeprogrammeprincipalsuivantutiliselaclasseVendeur. public class TestVendeur { public static void main(String[] args) { // initialisation du vendeur du systme Vendeur leVendeur = [Link](); [Link]("Vendeur Auto"); [Link]("Paris"); [Link]("vendeur@[Link]"); // affichage du vendeur du systme affiche(); } public static void affiche() { Vendeur leVendeur = [Link](); [Link](); } } Sonexcutionmontrebienquilnyaquuneseuleinstancecarlamthode affichedetestVendeurnereoitpasde paramtre. Nom : Vendeur Auto Adresse : Paris
- 2-
Email : vendeur@[Link]
- 3-
Prsentation
Lobjectif des patterns de structuration est de faciliter lindpendance de linterface dun objet ou dun ensemble dobjets visvis de son implantation. Dans le cas dun ensemble dobjets, il sagit aussi de rendre cette interface indpendantedelahirarchiedesclassesetdelacompositiondesobjets. En fournissant les interfaces, les patterns de structuration encapsulent la composition des objets, augmentant le niveau dabstraction du systme limage des patterns de cration qui encapsulent la cration des objets. Les patternsdestructurationmettentenavantlesinterfaces. Lencapsulation de la composition est ralise non pas en structurant lobjet luimme mais en transfrant cette [Link] le premier objet dtient linterface visvis des clients et gre la relation avec le second objet qui lui gre la compositionetnaaucuneinterfaceaveclesclientsexternes. Cette ralisation offre une autre proprit qui est la souplesse de la composition qui peut tre modifie [Link],ilestaisdesubstituerunobjetparunautrepourvuquilsoitissudelammeclasseou [Link],DecoratoretBridgeillustrentpleinementcemcanisme.
- 1-
Compositionstatiqueetdynamique
[Link] [Link]. Cest le cas de lutilisation de lhritage dune interface dans plusieurs classes dimplantation comme lillustre le diagrammedesclassesdelafigure9.1. [Link],unefoisquelechoixdelaclassedimplantation dunobjetesteffectu,ilnestpluspossibledenchanger.
Figure9.1Implantationdunobjetparhritage Commeexpliqudanslaprcdentesection,uneautresolutionestdesparerlaspectdimplantationdansunautre objet comme lillustre la figure 9.2. Les parties dimplantation sont gres par une instance de la classe ImplantationConcrteA ou par une instance de la classe ImplantationConcrteB. Cette instance est rfrence par [Link], lacompositionestdynamique.
- 1-
Touslespatternsdestructurationsontbasssurlutilisationdunoudeplusieursobjetsdterminantlastructuration. Lalistesuivantedcritlafonctionqueremplitcetobjetpourchaquepattern.
q
- 2-
Description
Le but du pattern Adapter est de convertir linterface dune classe existante en linterface attendue par des clients [Link] interfacepourrpondreauxbesoinsdeclients.
- 1-
Exemple
Le serveur web du systme de vente de vhicules cre et gre des documents destins aux clients. Linterface Document a t dfinie pour cette gestion. Sa reprsentation UML est montre la figure 10.1 ainsi que ses trois mthodes setContenu, dessine et imprime. Une premire classe dimplantation de cette interface a t ralise : la classe [Link] conus. Parlasuite,lajoutdesdocumentsPDFaposunproblmecarceuxcisontpluscomplexesconstruireetgrerque [Link] Document. Lafigure10.1montrelecomposant ComposantPdfdontlinterfaceintroduitplusdemthodesetdontlaconventionde nommageestdesurcrotdiffrente(prfixepdf). Lepattern Adapterproposeunesolutionquiconsistecrerlaclasse DocumentPdf implantant linterface Documentet possdant une association avec ComposantPdf. Limplantation des trois mthodes de linterface Document consiste dlguercorrectementlesappelsaucomposantPDF.Cettesolutionestvisiblesurlafigure10.1,lecodedesmthodes tantdtailllaidedenotes.
- 1-
Figure10.1LepatternAdapterappliquuncomposantdedocumentsPDF
- 2-
Structure
[Link]
Lafigure10.2dtaillelastructuregnriquedupattern.
Figure10.2StructuredupatternAdapter
[Link]
Lesparticipantsaupatternsontlessuivants:
- 1-
[Link]
Leclientinvoquelamthodedemandedeladaptateurqui,enconsquence,interagitaveclobjetadaptenappelant lamthodeaccomplit.Cescollaborationssontillustreslafigure10.3.
Figure10.3DiagrammedesquencedupatternAdapter
- 2-
Domainesdapplication
Lepatternestutilisdanslescassuivants:
q
- 1-
ExempleenJava
NousprsentonslecodesourcedelexempleenJava. NouscommenonsparlinterfaceDocument: public { void void void } interface Document setContenu(String contenu); dessine(); imprime();
LaclasseDocumentHtmlestlexempledeclasseimplantantlinterfaceDocument. public class DocumentHtml implements Document { String contenu; public void setContenu(String contenu) { [Link] = contenu; } public void dessine() { [Link]("Dessine document HTML : "+contenu); } public void imprime() { [Link]("Imprime document HTML : "+contenu); } } La classe ComposantPdf reprsente le composant existant qui est intgr dans lapplication. Sa conception est indpendantedelapplicationet,enparticulier,[Link]. public class ComposantPdf { String contenu; public void pdfFixeContenu(String contenu) { [Link] = contenu; } public void pdfPrpareAffichage() { [Link]("Affichage PDF : Dbut"); } public void pdfRafrachit() { [Link]("Affichage contenu PDF : "+contenu); } public void pdfTermineAffichage() { [Link]("Affichage PDF : Fin"); } public void pdfEnvoieImprimante() { [Link]("Impression PDF : "+contenu); } }
- 1-
La classe DocumentPdf reprsente ladaptateur. Elle est associe la classe ComposantPdf au travers de lattribut outilPdfquiassocielobjetadapt. Elleimplantelinterface Documentetchacunedesesmthodesinvoquelesmthodesncessairesdelobjetadaptafin deraliserladaptationentrelesdeuxinterfaces. public class DocumentPdf implements Document { ComposantPdf outilPdf = new ComposantPdf(); public void setContenu(String contenu) { [Link](contenu); } public void dessine() { [Link](); [Link](); [Link](); } public void imprime() { [Link](); } } Le programme principal correspond la classe ServeurWeb qui cre un document HTML, en fixe le contenu puis le dessine. Ensuite,leprogrammefaitlammechoseavecundocumentPDF. public class ServeurWeb { public static void main(String[] args) { Document document1,document2; document1 = new DocumentHtml(); [Link]("Hello"); [Link](); [Link](); document2 = new DocumentPdf(); [Link]("Bonjour"); [Link](); } } Lexcutiondeceprogrammeprincipaldonnelersultatsuivant. Dessine document HTML : Hello Affichage PDF : Dbut Affichage contenu PDF : Bonjour Affichage PDF : Fin
- 2-
Description
Le but du pattern Bridge est de sparer laspect dimplantation dun objet de son aspect de reprsentation et dinterface. Ainsi, dune part limplantation peut tre totalement encapsule et dautre part limplantation et la reprsentation peuventvoluerindpendammentetsansqueluneexerceunecontraintesurlautre.
- 1-
Exemple
Pour effectuer une demande dimmatriculation dun vhicule doccasion, il convient de prciser sur cette demande certaines informations importantes comme le numro de la plaque existante. Le systme affiche un formulaire pour demandercesinformations. Ilexistedeuximplantationsdesformulaires:
q
lesformulairesHTML lesformulairesbasssuruneappletJava.
Il est donc possible dintroduire une classe abstraite FormulaireImmatriculation et deux sousclasses concrtes FormulaireImmatriculationHtmletFormulaireImmatriculationApplet. Dans un premier temps, les demandes dimmatriculation ne concernaient que la France. Par la suite, il est devenu ncessaire dintroduire une nouvelle sousclasse de FormulaireImmatriculation correspondant aux demandes dimmatriculation au Luxembourg, sousclasse appele FormulaireImmatriculationLux. Cette sousclasse doit galement tre abstraite et avoir galement deux sousclasses concrtes pour chaque implantation. La figure 11.1 montrelediagrammedeclassescorrespondant.
Figure11.1Hirarchiedesformulairesintgrantlessousclassesdimplantation Cediagrammemetenavantdeuxproblmes:
q
Lahirarchiemlangeaummeniveaudessousclassesdimplantationetunesousclassedereprsentation: FormulaireImmatriculationLux. De plus pour chaque classe de reprsentation, il faut introduire deux sous classesdimplantation,cequiconduitrapidementunehirarchietrscomplexe. Les clients sont dpendants de limplantation. En effet, ils doivent interagir avec les classes concrtes dimplantation.
LasolutiondupatternBridgeconsistedoncsparerlesaspectsdereprsentationdeceuxdimplantationetcrer deux hirarchies de classes comme illustr la figure 11.2. Les instances de la classe FormulaireImmatriculation dtiennentlelienimplantationversuneinstancerpondantlinterfaceFormulaireImpl.
- 1-
Limplantation des mthodes de FormulaireImmatriculation est base sur lutilisation des mthodes dcrites dans FormulaireImpl. Quantlaclasse FormulaireImmatriculation,elleestmaintenantabstraiteetilexisteunesousclasseconcrtepour chaquepays( FormImmatriculationFranceetFormImmatriculationLuxembourg).
Figure11.2LepatternBridgeappliqulimplantationdeformulaires
- 2-
Structure
[Link]
Lafigure11.3dtaillelastructuregnriquedupattern.
- 1-
Figure11.3StructuredupatternBridge
[Link]
Lesparticipantsaupatternsontlessuivants:
q
ClasseAbstraite(FormulaireImmatriculation)estlaclasseabstraitequireprsentelesobjetsdudomaine. Elle dtient linterface pour les clients et contient une rfrence vers un objet rpondant linterface Implantation. ClasseConcrte (FormImmatriculationFranceet FormImmatriculationLuxembourg) est la classe concrte qui implantelesmthodesdeClasseAbstraite. Implantation(FormulaireImpl)[Link] ne doivent pas correspondre aux mthodes de ClasseAbstraite. Les deux ensembles de mthodes sont diffrents. Limplantation introduit en gnral des mthodes de bas niveau et les mthodes de ClasseAbstraitesontdesmthodesdehautniveau. ImplantationA, ImplantationB (FormHtmlImpl, FormAppletImpl) sont des classes concrtes qui ralisent les mthodesintroduitesdanslinterfaceImplantation.
[Link]
Les oprations de ClasseAbstraite et de ses sousclasses invoquent les mthodes introduites dans linterface Implantation.
- 2-
Domainesdapplication
Lepatternestutilisdanslescassuivants:
q
pour viter une liaison forte entre la reprsentation des objets et leur implantation, notamment quand limplantationestslectionneaucoursdelexcutiondelapplication pourqueleschangementsdanslimplantationdesobjetsnaientpasdimpactdanslesinteractionsentreles objetsetleursclients pourpermettrelareprsentationdesobjetsetleurimplantationdeconserverleurcapacitdextensionpar lacrationdenouvellessousclasses pourviterdobtenirdeshirarchiesdeclassesextrmementcomplexescommeillustrlafigure11.1.
- 1-
ExempleenJava
NousintroduisonsmaintenantunexempleenJavabassurlediagrammedeclassesdelafigure11.2. Nous commenons par linterface dcrivant limplantation des formulaires qui contient deux mthodes, lune pour afficheruntexteetlautrepourgrerunezonedesaisie. public interface FormulaireImpl { void dessineTexte(String texte); String greZoneSaisie(); } NousmontronslaclassedimplantationFormHtmlImplquisimulelaffichageetlasaisiedunformulaireHTML. import [Link].*; public class FormHtmlImpl implements FormulaireImpl { Scanner reader = new Scanner([Link]); public void dessineTexte(String texte) { [Link]("HTML : "+texte); } public String greZoneSaisie() { return [Link](); } } NousmontronslaclassedimplantationFormAppletImplquisimulelaffichageetlasaisiedunformulairelaidedune applet. import [Link]; public class FormAppletImpl implements FormulaireImpl { Scanner reader = new Scanner([Link]); public void dessineTexte(String texte) { [Link]("Applet : "+texte); } public String greZoneSaisie() { return [Link](); } } NouspassonslaclasseabstraiteFormulaireImmatriculation. Sonconstructeurprendenparamtreuneinstancegrantlimplantationetquiestutilisedanslesautresmthodes pourdessinerdutexteougrerlasaisiedentresauclavier. IlconvientdenoterlamthodecontrleSaisiequivrifiequelenumroduneplaquedimmatriculationestcorrect,ce [Link]. public abstract class FormulaireImmatriculation { String contenu; FormulaireImpl implantation; public FormulaireImmatriculation(FormulaireImpl implantation) { [Link] = implantation;
- 1-
} public void affiche() { [Link]("numro de la plaque existante : "); } public void gnreDocument() { [Link]("Demande dimmatriculation"); [Link]("numro de plaque : " + contenu); } public boolean greSaisie() { contenu = [Link](); return [Link](contenu); } protected abstract boolean contrleSaisie(String plaque); } LasousclasseconcrtedeformulairedimmatriculationenFranceimplantelamthode contrleSaisiequivrifieque lenumrodelaplaqueaunelongueurcompriseentre7et8. public class FormImmatriculationFrance extends FormulaireImmatriculation { FormImmatriculationFrance(FormulaireImpl implantation) { super(implantation); } protected boolean contrleSaisie(String plaque) { return ([Link]()>=7) && ([Link]()<=8); } } LasousclasseconcrtedeformulairedimmatriculationauLuxembourgimplantelamthodecontrleSaisiequivrifie quelenumrodelaplaqueaunelongueurde5. public class FormImmatriculationLuxembourg extends FormulaireImmatriculation { FormImmatriculationLuxembourg(FormulaireImpl implantation) { super(implantation); } protected boolean contrleSaisie(String plaque) { return [Link]()==5; } } Enfin, nous prsentons le programme principal de la classe Utilisateur qui cre un formulaire de gnration dun documentdedemandedimmatriculationpourleLuxembourgetsisasaisieestcorrecteafficheledocumentlcran. Ensuite,leprogrammefaitlammechoseavecundocumentdedemandedimmatriculationpourlaFrance. public class Utilisateur { public static void main(String[] args) { FormImmatriculationLuxembourg formulaire1 = new FormImmatriculationLuxembourg(new FormHtmlImpl());
- 2-
[Link](); if ([Link]()) [Link](); [Link](); FormImmatriculationFrance formulaire2 = new FormImmatriculationFrance(new FormAppletImpl()); [Link](); if ([Link]()) [Link](); } } Unexempledexcutionestlesuivant(lesnumrosdeplaquesintroduitssont2345Xet97AAA59). HTML : numro de la plaque existante : 2345X HTML : Demande dimmatriculation HTML : numro de plaque : 2345X Applet : numro de la plaque existante : 97AAA59 Applet : Demande dimmatriculation Applet : numro de plaque : 97AAA59
- 3-
Description
Le but du pattern Composite est doffrir un cadre de conception dune composition dobjets dont la profondeur est variable,cetteconceptiontantbasesurunarbre. Par ailleurs, cette composition est encapsule visvis des clients des objets qui peuvent interagir sans devoir connatrelaprofondeurdelacomposition.
- 1-
Exemple
Au sein de notre systme de vente de vhicules, nous voulons reprsenter les socits clientes, notamment pour connatrelenombredevhiculesdontellesdisposentetleurproposerdesoffresdemaintenancedeleurparc. Les socits qui possdent des filiales demandent des offres de maintenance qui prennent en compte le parc de vhiculesdeleursfiliales. Une solution immdiate consiste traiter diffremment les socits sans filiale et celle possdant des filiales. Cependant cette diffrence de traitement entre les deux types de socit rend lapplication plus complexe et dpendantedelacompositioninternedessocitsclientes. Le pattern Composite rsout ce problme en unifiant linterface des deux types de socits et en utilisant la composition rcursive. Cette composition rcursive est ncessaire car une socit peut possder des filiales qui [Link](nousfaisonslhypothsedelabsencede filialecommuneentredeuxsocits)commeillustrelafigure12.1olessocitsmressontplacesaudessusde leursfiliales.
Figure12.1Arbredesocitsmresetdeleursfiliales La figure 12.2 introduit le diagramme des classes correspondant. La classe abstraite Socit dtient linterface destine aux clients. Elle possde deux sousclasses concrtes savoir SocitSansFiliale et SocitMre, cette derniredtenantuneassociationdagrgationaveclaclasseSocitreprsentantlesliensavecsesfiliales.
- 1-
Figure12.2LepatternCompositeappliqulareprsentationdesocitsetdeleursfiliales Laclasse Socitpossdetroismthodespubliquesdontuneseuleestconcrteetlesdeuxautressontabstraites. La mthode concrte est la mthode ajouteVhicule qui ne dpend pas de la composition en filiales de la socit. Quantauxdeuxautresmthodes,ellessontimplantesdanslessousclassesconcrtes( ajouteFilialenepossde quuneimplantationvidedansSocitSansFilialedoncellenestpasreprsentedanslediagrammedeclasses).
- 2-
Structure
[Link]
Lafigure12.3dtaillelastructuregnriquedupattern.
Figure12.3StructuredupatternComposite
[Link]
- 1-
Lesparticipantsaupatternsontlessuivants:
q
Composant (Socit)estlaclasseabstraitequiintroduitlinterfacedesobjetsdelacomposition,implanteles mthodes communes et introduit la signature des mthodes qui grent la composition en ajoutant ou en supprimantdescomposants Feuille (SocitSansFiliale)est la classe concrte qui dcrit les feuilles de la composition (une feuille ne possdepasdecomposants) Compos (SocitMre)est la classe concrte qui dcrit les objets composs de la hirarchie. Cette classe possdeuneassociationdagrgationaveclaclasseComposant Clientestlaclassedesobjetsquiaccdentauxobjetsdelacompositionetquilesmanipulent.
[Link]
LesclientsenvoientleursrequtesauxcomposantsautraversdelinterfacedelaclasseComposant. Lorsquuncomposantreoitunerequte,[Link],iltraitela requtecommeillustrlafigure12.4.
- 2-
Figure12.5Traitementdunmessageparuncompos
- 3-
Domainesdapplication
Lepatternestutilisdanslescassuivants:
q
ilestncessairedereprsenterauseindunsystmedeshirarchiesdecomposition lesclientsdunecompositiondoiventignorersilscommuniquentavecdesobjetscompossounon.
- 1-
ExempleenJava
Nousreprenonslexempledessocitsetdelagestiondeleurparcdevhicules. Laclasseabstraite [Link] unrsultatboolenquiindiquesilajoutapuounontreralis. public abstract class Socit { protected static double cotUnitVhicule = 5.0; protected int nbrVhicules; public void ajouteVhicule() { nbrVhicules = nbrVhicules + 1; } public abstract double calculeCotEntretien(); public abstract boolean ajouteFiliale(Socit filiale); } Le code source de la classe SocitSansFiliale est fourni la suite. Les instances de cette classe ne peuvent pas ajouterdefiliales. public class SocitSansFiliale extends Socit { public boolean ajouteFiliale(Socit filiale) { return false; } public double calculeCotEntretien() { return nbrVhicules*cotUnitVhicule; } } Ensuite,laclasse [Link] calculeCotEntretiendontle rsultatestlasommeducotdesfilialesetducotdelasocitmre. import [Link].*; public class SocitMre extends Socit { List<Socit> filiales = new ArrayList<Socit>(); public boolean ajouteFiliale(Socit filiale) { return [Link](filiale); } public double calculeCotEntretien() { double cot = 0.0; for (Socit filiale : filiales) cot = cot+[Link](); return cot+nbrVhicules*cotUnitVhicule; } } Enfin,[Link]. [Link] quatrevhicules,pouruncottotaldentretiende20(lecotpourunvhiculeestde5). public class Utilisateur { public static void main(String[] args) {
ENI Editions - All rigths reserved - Algeria Educ - 1-
Socit socit1 = new SocitSansFiliale(); [Link](); Socit socit2 = new SocitSansFiliale(); [Link](); [Link](); Socit groupe = new SocitMre(); [Link](socit1); [Link](socit2); [Link](); [Link](" Cot dentretien total du groupe : "+ [Link]()); } } Lexcutionduprogrammefournitbienlersultatde20: Cot dentretien total du groupe : 20.0
- 2-
Description
Lebutdupattern Decorator est [Link] defonctionnalitsnemodifiepaslinterfacedelobjetetrestedonctransparentvisvisdesclients. LepatternDecoratorconstitueunealternativeparrapportlacrationdunesousclassepourenrichirunobjet.
- 1-
Exemple
Le systme de vente de vhicules dispose dune classe VueCatalogue qui affiche, sous la forme dun catalogue lectronique,lesvhiculesdisponiblessurunepageweb. Nous voulons maintenant afficher des donnes supplmentaires pour les vhicules "haut de gamme", savoir les [Link],nouspouvonsraliserunesous classe daffichage spcifique pour les vhicules "haut de gamme". Maintenant, nous voulons afficher le logo de la marque des vhicules "moyen et haut de gamme". Il convient alors dajouter une nouvelle sousclasse pour ces vhicules, surclasse de la classe des vhicules "haut de gamme", ce qui devient vite complexe. Il est ais de comprendreiciquelutilisationdelhritagenestpasadaptecequiestdemandpourdeuxraisons:
q
lhritageestunoutiltroppuissantpourraliseruntelajoutdefonctionnalit, lhritageestunmcanismestatique.
Le pattern Decorator propose une autre approche qui consiste ajouter un nouvel objet appel dcorateur qui se substitue lobjet initial et qui le rfrence. Ce dcorateur possde la mme interface ce qui rend la substitution transparente visvis des clients. Dans notre cas, la mthode affiche est alors intercepte par le dcorateur qui demandelobjetinitialdesafficherpuisafficheensuitedesinformationscomplmentaires. La figure 13.1 illustre lutilisation du pattern Decorator pour enrichir laffichage de vhicules. Linterface ComposantGraphiqueVhiculeconstituelinterfacecommunelaclasse VueVhicule,quenousvoulonsenrichir,etla classeabstraiteDcorateur,interfaceuniquementconstituedelamthodeaffiche. [Link] affichequidlguelaffichageverscecomposant.
- 1-
Figure13.1LepatternDecoratorpourlaffichagedevhiculesdansuncataloguelectronique Il existe deux classes concrtes de dcorateur, sousclasses de Dcorateur. Leur mthode affiche commence par
- 2-
appeler la mthode affiche de Dcorateur puis affiche les donnes complmentaires comme les informations techniquesdumodleoulelogodelamarque. Lafigure13.2montrelasquencedesappelsdemessagedestinslaffichagedunvhiculepourlequellelogodela marqueestgalementaffich.
Figure13.2Diagrammedesquencedelaffichagedunvhiculeaveclelogodesamarque La figure 13.3 montre la squence des appels de message destins laffichage dun vhicule pour lequel les informationstechniquesdumodleetlelogodelamarquesontgalementaffichs. Cettefigureillustrebienlefaitquelesdcorateurssontdescomposantspuisquilspeuventdevenirlecomposantdun nouveau dcorateur, ce qui donne lieu une chane de dcorateurs. Cette possibilit de chane dans laquelle il est possibledajouterouderetirerdynamiquementundcorateurprocureunegrandesouplesse.
- 3-
Figure13.3Diagrammedesquencedelaffichagedunvhiculeaveclesinformationstechniquesdesonmodleet lelogodesamarque
- 4-
Structure
[Link]
Lafigure13.4dtaillelastructuregnriquedupattern.
Figure13.4StructuredupatternDecorator
[Link]
Lesparticipantsaupatternsontlessuivants:
q
ComposantAbstrait dcorateurs
(ComposantGraphiqueVhicule)est
linterface
commune
au
composant
et
aux
- 1-
[Link]
Le dcorateur se substitue au composant. Lorsquil reoit un message destin ce dernier, il le redirige au composanteneffectuantdesoprationspralablesoupostrieurescetteredirection.
- 2-
Domainesdapplication
LepatternDecoratorpeuttreutilisdanslesdomainessuivants:
q
Un systme ajoute dynamiquement des fonctionnalits un objet, sans modifier son interface, cestdire sansquelesclientsdecetobjetdoiventtremodifis. Unsystmegredesfonctionnalitsquipeuventtreretiresdynamiquement. Lutilisationdelhritagepourtendredesobjetsnestpaspratique,cequipeutarriverquandleurhirarchie estdjcomplexe.
- 1-
ExempleenJava
NousprsentonslecodesourceJavadelexemple,encommenantparlinterfaceComposantGraphiqueVhicule. public interface ComposantGraphiqueVhicule { void affiche(); } LaclasseVueVhiculeimplantelamthodeaffichedelinterfaceComposantGraphiqueVhicule. public class VueVhicule implements ComposantGraphiqueVhicule { public void affiche() { [Link]("Affichage du vhicule"); } } Laclasse Dcorateurimplantegalementlamthode [Link] [Link]. public abstract class Dcorateur implements ComposantGraphiqueVhicule { ComposantGraphiqueVhicule composant; Dcorateur(ComposantGraphiqueVhicule composant) { [Link] = composant; } public void affiche() { [Link](); } } La mthode affiche du dcorateur concret ModleDcorateur appelle laffichage du composant (au travers de la mthodeaffichedeDcorateur)puisaffichelesinformationstechniquesdumodle. public class ModleDcorateur extends Dcorateur { ModleDcorateur(ComposantGraphiqueVhicule composant) { super(composant); } protected void afficheInfosTechniques() { [Link]("Informations techniques du modle"); } public void affiche() { [Link](); [Link](); } } LamthodeaffichedudcorateurconcretMarqueDcorateurappellelaffichageducomposantpuisaffichelelogodela marque. public class MarqueDcorateur extends Dcorateur { MarqueDcorateur(ComposantGraphiqueVhicule composant) {
- 1-
super(composant); } protected void afficheLogo() { [Link]("Logo de la marque"); } public void affiche() { [Link](); [Link](); } } Enfin, la classe VueCatalogue est le programme principal. Ce programme cre une vue de vhicule, un dcorateur de modlequiprendlavuecommecomposant,puisundcorateurdemarquequiprendledcorateurdemodlecomme [Link],ceprogrammedemandelaffichageaudcorateurdemarque. public class VueCatalogue { public static void main(String[] args) { VueVhicule vueVhicule = new VueVhicule(); ModleDcorateur modleDcorateur = new ModleDcorateur(vueVhicule); MarqueDcorateur marqueDcorateur = new MarqueDcorateur(modleDcorateur); [Link](); } } Lersultatestlesuivant: Affichage du vhicule Informations techniques du modle Logo de la marque
- 2-
Description
LobjectifdupatternFacadeestderegrouperlesinterfacesdunensembledobjetsenuneinterfaceunifierendantcet ensembleplussimpleutiliserpourunclient. LepatternFacadeencapsulelinterfacedechaqueobjetconsidrecommeinterfacedebasniveaudansuneinterface [Link] composerlesinterfacesdebasniveau.
- 1-
Exemple
[Link] architectursouslaformedunensembledecomposantspossdantleurpropreinterfacecomme:
q
Ilestpossiblededonnerlaccslensembledelinterfacedecescomposantsauxclientsduservicewebmaiscette dmarcheprsentedeuxinconvnientsmajeurs:
q
Le pattern Facade rsout ce problme en proposant lcriture dune interface unifie plus simple et dun plus haut [Link]. Cette solution est illustre la figure 14.1. La classe WebServiceAuto offre une interface aux clients du service web. Cetteclasseetsoninterfaceconstituentunefaadevisvisdecesclients. LinterfacedelaclasseWebServiceAutoesticiconstituedelamthode chercheVhicules(prixMoyen,cartMax)dontle code consiste appeler la mthode retrouveVhicules(prixMin, prixMax) du catalogue en adaptant la valeur des argumentsdecettemthodeenfonctionduprixmoyenetdelcartmaximum. Il convient de noter que si lide du pattern est de constituer une interface de plus haut niveau dabstraction, rien nempche de fournir galement dans la faade des accs directs aux mthodes des composantsdusystme.
- 1-
Figure14.1ApplicationdupatternFacadelamiseenuvredunservicewebdusystmedeventedevhicules
- 2-
Structure
[Link]
Lafigure14.2dtaillelastructuregnriquedupattern.
Figure14.2StructuredupatternFacade
[Link]
Lesparticipantsaupatternsontlessuivants:
q
Faade (WebServiceAuto) et son interface constituent la partie abstraite expose aux clients du systme. Cette classe possde des rfrences vers les classes et composants constituant le systme et dont les mthodessontutilisesparlafaadepourimplanterlinterfaceunifie Les classes et composants du systme ( RepriseVhicule, GestionDocument et Catalogue) implantent les [Link] travailler.
- 1-
[Link]
Lesclientscommuniquentaveclesystmeautraversdelafaadequisecharge,sontour,dinvoquerlesclasseset composants du systme. La faade ne peut pas se limiter transmettre des invocations. Elle doit aussi raliser [Link] squence de la figure 14.3 illustre cette adaptation sur un exemple o du code spcifique la faade doit tre invoqu(mthodescalcule1etcalcule2). Lesclientsquiutilisentlafaadenedoiventpasaccderdirectementauxobjetsdusystme.
Figure14.3Appeldecodespcifiquencessairepourladaptationdesmthodesdelafaade
- 2-
Domainesdapplication
Lepatternestutilisdanslescassuivants:
q
[Link] nombreuses petites classes, lui offrant une bonne modularit et des capacits dvolution. Cependant ces bonnespropritsdusystmenintressentpassesclientsquiontbesoindunaccssimplequirpondleurs exigences pour diviser un systme en soussystmes, la communication entre soussystmes tant mise en uvre de faonabstraitedeleurimplantationgrceauxfaades poursystmatiserlencapsulationdelimplantationdunsystmevisvisdelextrieur.
- 1-
ExempleenJava
[Link] dabord le code source des composants du systme et pour commencer celui de la classe ComposantCatalogue et de soninterfaceCatalogue. La base de donnes constituant le catalogue est remplace par un simple tableau dobjets. La mthode retrouveVhicules effectue la recherche dun ou de plusieurs vhicules en fonction de leur prix laide dunesimple boucle. import [Link].*; public interface Catalogue { List<String> retrouveVhicules(int prixMin,int prixMax); }
public class ComposantCatalogue implements Catalogue { Object[] descriptionsVhicule= { "Berline 5 portes",6000, "Compact 3 portes",4000, "Espace 5 portes",8000, "Break 5 portes",7000, "Coup 2 portes",9000, "Utilitaire 3 portes",5000 }; public List<String> retrouveVhicules(int prixMin, int prixMax) { int index,taille; List<String> rsultat = new ArrayList<String>(); taille = [Link]/2; for (index=0;index<taille;index++) { int prix= ((Integer)descriptionsVhicule[2*index+1]).intValue(); if ((prix >= prixMin) && (prix <= prixMax)) [Link]((String)descriptionsVhicule[2*index]); } return rsultat; } } Nouscontinuonsaveclecomposantdegestiondedocumentsconstitudelinterface GestionDocumentetdelaclasse [Link]. public interface GestionDocument { String document(int index); } public class ComposantGestionDocument implements GestionDocument { public String document(int index) { return "Document numro "+index; } } Linterface de la faade appele WebServiceAuto introduit la signature de deux mthodes destines aux clients du serviceweb. import [Link];
ENI Editions - All rigths reserved - Algeria Educ - 1-
public interface WebServiceAuto { String document(int index); List<String> chercheVhicules(int prixMoyen,int cartMax); } La classe WebServiceAutoImpl implante ces deux mthodes. Remarquons le calcul du prix minimum et maximum pour pouvoirinvoquerlamthoderetrouveVhiculesdelaclasseComposantCatalogue. import [Link]; public class WebServiceAutoImpl implements WebServiceAuto { Catalogue catalogue = new ComposantCatalogue(); GestionDocument gestionDocument = new ComposantGestionDocument(); public String document(int index) { return [Link](index); } public List<String> chercheVhicules(int prixMoyen, int cartMax) { return [Link](prixMoyen-cartMax, prixMoyen+cartMax); } } Enfin,unclientduservicewebpeutscrireenJavacommesuit: import [Link].*; public class UtilisateurWebService { public static void main(String[] args) { WebServiceAuto webServiceAuto = new WebServiceAutoImpl(); [Link]([Link](0)); [Link]([Link](1)); List<String> rsultats = [Link](6000, 1000); if ([Link]() > 0) { [Link]( "Vhicule(s) dont le prix est compris entre 5000 et 7000"); for (String rsultat : rsultats) [Link](" "+rsultat); } } } Ce client affiche deux documents ainsi que les vhicules dont le prix est compris entre 5000 et 7000. Le rsultat de lexcutiondeceprogrammeprincipalestlesuivant: Document numro 0 Document numro 1 Vhicule(s) dont le prix est compris entre 5000 et 7000 Berline 5 portes Break 5 portes Utilitaire 3 portes
- 2-
Description
LebutdupatternFlyweightestdepartagerdefaonefficaceunensembleimportantdobjetsdegrainfin.
- 1-
Exemple
Dans le systme de vente de vhicules, il est ncessaire de grer les options que lacheteur peut choisir lorsquil commandeunnouveauvhicule. Cesoptionssontdcritesparlaclasse OptionVhiculequicontientplusieursattributscommelenom,lexplication,un logo,leprixstandard,lesincompatibilitsavecdautresoptions,aveccertainsmodles,etc. Pourchaquevhiculecommand,[Link] nombredoptionssontsouventprsentespourchaquevhiculecommand,cequiobligelesystmegrerungrand ensembledobjetsdepetitetaille(degrainfin).Cetteapprocheprsentetoutefoislavantagedepouvoirstockerau niveau de loption des informations spcifiques celleci et au vhicule comme le prix de vente de loption qui peut diffrerdunvhiculecommandunautre. Cette solution est prsente sur un petit exemple la figure 15.1 et il est ais de se rendre compte quun grand nombre dinstances de OptionVhicule doit tre gr alors que nombre dentre elles contiennent des donnes identiques.
Figure15.1Exempledabsencedepartagedobjetsdegrainfin LepatternFlyweightproposeunesolutionceproblmeenpartageantlesoptions:
q
le partage est ralis par une fabrique laquelle le systme sadresse pour obtenir une rfrence vers une [Link],lafabriqueprocdesacrationavantdenrenvoyer larfrence les attributs dune option ne contiennent que ses informations spcifiques indpendamment des vhicules commands:cesinformationsconstituentltatintrinsquedesoptions les informations particulires une option et un vhicule sont stockes au niveau du vhicule : ces informations constituent ltat extrinsque des options. Elles sont transmises comme paramtres lors des appelsdesmthodesdesoptions. Danslecadredecepattern,lesoptionssontlesobjetsappelsflyweights(poidsmoucheenfranais).
Lafigure15.2illustrelediagrammedesclassesdecettesolution.
- 1-
Figure15.2LepatternFlyweightappliqudesoptionsdevhicules Cediagrammeintroduitlesclassessuivantes:
q
OptionVhicule dont les attributs dtiennent ltat intrinsque dune option. Les mthodes affiche et enregistreontpourparamtreprixDeVentequireprsenteltatextrinsqueduneoption FabriqueOption dont la mthode getOption renvoie une option partir de son nom. Son fonctionnement consisterechercherloptiondanslassociationqualifieetlacrerdanslecascontraire VhiculeCommandquipossdeunelistedesoptionscommandesainsiqueleurprixdevente.
- 2-
Structure
[Link]
Lafigure15.3dtaillelastructuregnriquedupattern.
Figure15.3StructuredupatternFlyweight
[Link]
Lesparticipantsaupatternsontlessuivants:
q
FabriqueFlyweight (FabriqueOption)[Link] partagsgrcelamthodegetFlyweightquirenvoielesrfrencesverslesflyweights Flyweight (OptionVhicule)dtient [Link] dterminentgalementltatextrinsquedesflyweights Client (VhiculeCommand)[Link] galementdtenirltatextrinsquedecesflyweights.
[Link]
Les clients ne doivent pas crer euxmmes les flyweights mais utiliser la mthode getFlyweight de la classe
- 1-
FabriqueFlyweightquigarantitquelesflyweightssontpartags. Lorsquunclientinvoqueunemthodedunflyweight,ildoitluitransmettresontatextrinsque.
- 2-
Domainedapplication
LedomainedapplicationdupatternFlyweightestlepartagedepetitsobjets(poidsmouche).Lescritresdutilisation sontlessuivants:
q
- 1-
ExempleenJava
La classe OptionVhicule possde un constructeur qui permet de dfinir ltat intrinsque de loption. Dans cet exemple, part le nom, les autres attributs prennent des valeurs constantes ou bases directement sur le nom. Normalement,cesvaleursdevraientprovenirdunebasededonnes. Lamthodeafficheprendleprixdeventecommeparamtrequiconstitueltatextrinsque. public class OptionVhicule { protected String nom; protected String description; protected int prixStandard; OptionVhicule(String nom) { [Link] = nom; [Link] = "Description de "+nom; [Link] = 100; } public void affiche(int prixDeVente) { [Link]("Option"); [Link]("Nom : "+nom); [Link](description); [Link]("Prix standard : "+prixStandard); [Link]("Prix de vente : "+prixDeVente); } } Laclasse FabriqueOptiongrelepartagedesoptionslaidedundictionnaire(TreeMap)dontlacldaccsestlenom de loption. La mthode getOption recherche dans ce dictionnaire et si loption nest pas trouve, elle est cre, ajouteaudictionnaireetretourne. import [Link].*; public class FabriqueOption { protected Map<String,OptionVhicule> options = new TreeMap<String,OptionVhicule>(); OptionVhicule getOption(String nom) { OptionVhicule rsultat; rsultat = [Link](nom); if (rsultat == null) { rsultat = new OptionVhicule(nom); [Link](nom, rsultat); } return rsultat; } } [Link] [Link] listeoption. La mthode ajouteOptions prend comme paramtres le nom de loption (tat intrinsque), le prix de vente (tat extrinsque)etlafabriquedoptionsutiliser. Lorsdelappeldelamthodeafficheduneoption,sonprixdeventeesttransmisenparamtrecommeilestpossible desenapercevoirdanslamthodeafficheOptions. import [Link].*; public class VhiculeCommand { List<OptionVhicule> options =
- 1-
new ArrayList<OptionVhicule>(); List<Integer> prixDeVenteOptions = new ArrayList<Integer>(); public void ajouteOptions(String nom, int prixDeVente, FabriqueOption fabrique) { [Link]([Link](nom)); [Link](prixDeVente); } public void afficheOptions() { int index, taille; taille = [Link](); for (index=0; index<taille; index++) { [Link](index).affiche( [Link](index).intValue()); [Link](); } } } Enfin,[Link], unvhiculecommand,luiajoutetroisoptionspuislesaffiche. public class Client { public static void main(String[] args) { FabriqueOption fabrique = new FabriqueOption(); VhiculeCommand vhicule = new VhiculeCommand(); [Link]("air bag", 80, fabrique); [Link]("direction assiste", 90, fabrique); [Link]("vitres lectriques", 85, fabrique); [Link](); } } Lersultatdelexcutiondeceprogrammeestlesuivant(affichagedestroisoptions,avecleurstatsintrinsqueet extrinsque). Option Nom : air bag Description de air bag Prix standard : 100 Prix de vente : 80 Option Nom : direction assiste Description de direction assiste Prix standard : 100 Prix de vente : 90 Option Nom : vitres lectriques Description de vitres lectriques Prix standard : 100 Prix de vente : 85
- 2-
Description
LepatternProxyapourobjectiflaconceptiondunobjetquisesubstitueunautreobjet(lesujet)etquiencontrle laccs. Lobjetquieffectuelasubstitutionpossdelammeinterfacequelesujet,cequirendcettesubstitutiontransparente visvisdesclients.
- 1-
Exemple
[Link] clicsurlaphotodelaprsentationduvhiculepermetdejouercefilm. Une page du catalogue contient de nombreux vhicules et il est trs lourd de crer en mmoire tous les objets danimationcarlesfilmsncessitentunegrandequantitdemmoireetleurtransfertautraversdun rseau prend beaucoupdetemps. Lepattern Proxyoffreunesolutionceproblmeendiffrantlacrationdessujetsjusquaumomentolesystmea besoindeux,[Link]:
q
Lobjet photo est appel le proxy du film. Il se substitue au film pour laffichage. Il procde la cration du sujet [Link].Lafigure16.1montrelediagrammedesclasses correspondant. La classe du proxy, AnimationProxy, et la classe du film, Film, implantent toutes les deux la mme interface,savoirAnimation.
- 1-
message clic, il joue le fim aprs avoir pralablement cr et charg le film. Le diagramme de squence pour le messagedessineestdtailllafigure16.2etlafigure16.3pourlemessageclic.
Figure16.2Diagrammedesquencedumessageclic
- 2-
Figure16.3Diagrammedesquencedumessagedessine
- 3-
Structure
[Link]
Lafigure16.4illustrelastructuregnriquedupattern.
[Link]
Lesparticipantsaupatternsontlessuivants:
q
Proxy (AnimationProxy)est lobjet qui se substitue au sujet rel. Il possde une interface identique ce dernier(interfaceSujet).Ilestchargdecreretdedtruirelesujetreletdeluidlguerlesmessages.
[Link]
[Link],ildlguecesmessagesau [Link],danscecas,crerpralablementlesujetrelsicenestdjfait.
- 2-
Domainesdapplication
[Link]:
q
- 1-
ExempleenJava
[Link]. public interface Animation { void dessine(); void clic(); } [Link],chaque mthodeaffichesimplementunmessagelexceptiondelamthodeclicquinapasdaction. public class Film implements Animation { public void clic() { } public void dessine() { [Link]("Affichage du film"); } public void charge() { [Link]("Chargement du film"); } public void joue() { [Link]("Lecture du film"); } } Lecodesourceduproxy,[Link] lediagrammedesclassesdelafigure16.1. public class AnimationProxy implements Animation { Film film = null; public void clic() { if (film == null) { film = new Film(); [Link](); } [Link](); } public void dessine() { if (film != null) [Link](); else [Link]("affichage de la photo"); } } Enfin,laclasseVueVhiculequireprsenteleprogrammeprincipalscritcommesuit. public class VueVhicule { public static void main(String[] args) { Animation animation = new AnimationProxy();
- 1-
[Link](); [Link](); [Link](); } } Lexcution de ce programme montre la diffrence de comportement de la mthode dessine du proxy selon que la mthodeclicatounonpralablementinvoque. affichage de la photo Chargement du film Lecture du film Affichage du film
- 2-
Prsentation
[Link] ralisepartirdesdeuxaspectssuivants:
q
lastructurationdesdonnes ladistributiondestraitementsetdesalgorithmes.
Lespatternsdestructurationapportentdessolutionsauxproblmesdestructurationdesdonnesetdesobjets. Lobjectifdespatternsdecomportementestdefournirdessolutionspourdistribuerlestraitementsetlesalgorithmes entrelesobjets. Ces patterns organisent les objets ainsi que leurs interactions en spcifiant les flux de contrle et de traitement au seindunsystmedobjets.
- 1-
Distributionparhritageoupardlgation
[Link] [Link] peut possder plusieurs sousclasses, cette approche autorise la possibilit dobtenir des variantes des parties [Link] uvreparlepattern Template Methodcommelillustrela figure17.1.
Figure17.1LarpartitiondestraitementsparhritageillustreparlepatternTemplate Method Unesecondepossibilitderpartitionestmiseen uvreparladistributiondestraitementsdansdesobjetsdontles classes sont indpendantes. Dans cette approche, un ensemble dobjets cooprant entre eux concourent la [Link] [Link] demandedelaclasse Entitinvoquepourlaralisationdesontraitementlamthode calculespcifieparlinterface [Link].
- 1-
Command Interpreter Iterator Mediator Memento Observer State Strategy TemplateMethod Visitor
Dlgation Hritage Dlgation Dlgation Dlgation Dlgation Dlgation Dlgation Hritage Dlgation
- 2-
Description
Le pattern Chain of Responsibility construit une chane dobjets telle que si un objet de la chane ne peut pas rpondreunerequte,ilpuisselatransmettresonsuccesseuretainsidesuitejusqucequelundesobjetsdela chaneyrponde.
- 1-
Exemple
[Link], lutilisateur peut demander une description de lun des vhicules mis en vente. Si une telle description na pas t fournie, le systme doit alors renvoyer la description associe au modle de ce vhicule. Si nouveau, cette descriptionnapastfournie,[Link] pardfautestrenvoyesilnyapasnonplusdedescriptionassocielamarque. Ainsi,lutilisateurreoitladescriptionlaplusprcisequiestdisponibledanslesystme. Lepattern Chain of Responsibilityfournitunesolutionpourmettreen [Link] les objets entre eux du plus spcifique (le vhicule) au plus gnral (la marque) pour former la chane de [Link] etrenvoyerladescription. LediagrammedobjetsUMLdelafigure18.1illustrecettesituationetmontrelesdiffrenteschanesderesponsabilit (delagaucheversladroite).
Figure18.1Diagrammedobjetsdevhicules,modlesetmarquesaveclesliensdelachanederesponsabilit La figure 18.2 reprsente le diagramme des classes du pattern Chain of Responsibility appliqu lexemple. Les vhicules, modles et marques sont dcrits par des sousclasses concrtes de la classe ObjetBase. Cette classe abstraite introduit lassociation suivant qui implante la chane de responsabilit. Elle introduit galement trois mthodes:
q
[Link] doitretournersoitladescriptionsielleexistesoitlavaleurnulldanslecascontraire descriptionParDfaut retourne une valeur de description par dfaut, valable pour tous les vhicules du catalogue getDescription est la mthode publique destine lutilisateur. Elle invoque la mthode description. Si le rsultat est null, alors sil y a un objet suivant, sa mthode getDescription est invoque son tour sinon cestlamthodedescriptionParDfautquiestutilise.
- 1-
Figure18.2LepatternChain of Responsibilitypourorganiserladescriptiondevhiculesdoccasion La figure 18.3 montre un diagramme de squence qui est un exemple de requte dune description base sur le diagrammedobjetsdelafigure18.1. Danscetexemple,nile vhicule1,nile [Link] marque1possdeunedescription quiestdoncutilisepourlevhicule1.
Figure18.3DiagrammedesquenceillustrantsurunexemplelepatternChain of Responsibility
- 2-
Structure
[Link]
Lafigure18.4dtaillelastructuregnriquedupattern.
Figure18.4StructuredupatternChain of Responsibility
[Link]
Lesparticipantsaupatternsontlessuivants:
q
Gestionnaire (ObjetBase)est une classe abstraite qui implante sous forme dune association la chane de responsabilitainsiquelinterfacedesrequtes
- 1-
GestionnaireConcret1et GestionnaireConcret2 (Vhicule, Modle et Marque) sont les classes concrtes qui implantent le traitement des requtes en utilisant la chane de responsabilit si elles ne peuvent pas les traiter Client (Utilisateur)initielarequteinitialeauprsdunobjetdelunedesclassesGestionnaireConcret1ou GestionnaireConcret2.
[Link]
Le client effectue la requte initiale auprs dun gestionnaire. Cette requte est propage le long de la chane de responsabilitjusquaumomentolundesgestionnaireslatraite.
- 2-
Domainesdapplication
Lepatternestutilisdanslescassuivants:
q
unechanedobjetsgreunerequteselonunordrequiestdfinidynamiquement lafaondontunechanedobjetsgreunerequtenedoitpastreconnuedesesclients.
- 1-
ExempleenJava
Nous introduisons maintenant [Link] ObjetBase est dcrite la suite. Elle implante la chane de responsabilit par lattribut suivant dont la valeur peut tre fixe par la mthode setSuivant. Les autres mthodescorrespondentauxspcificationsintroduitesdanslafigure18.2. public abstract class ObjetBase { protected ObjetBase suivant; private String descriptionParDfaut() { return "description par dfaut"; } protected abstract String description(); public String getDescription() { String rsultat; rsultat = [Link](); if (rsultat != null) return rsultat; if (suivant != null) return [Link](); else return [Link](); } public void setSuivant(ObjetBase suivant) { [Link] = suivant; } } Les trois sousclasses concrtes de la classe ObjetBase sont Vhicule, Modle et Marque, leur code source Java est prsent la suite. La classe Vhicule gre une description simple fournie au moment de sa construction (le paramtrenullestutilisencasdabsencededescription). public class Vhicule extends ObjetBase { String description; public Vhicule(String description) { [Link] = description; } protected String description() { return description; } } LaclasseModlegreunedescriptionetunnom. public class Modle extends ObjetBase { String description; String nom; public Modle(String nom, String description) { [Link] = description; [Link] = nom; } protected String description()
- 1-
{ if (description != null) return "Modle "+nom+" : "+description; else return null; } } LaclasseMarquegredeuxdescriptionsetunnom. public class Marque extends ObjetBase { String description1, description2; String nom; public Marque(String nom, String description1, String description2) { this.description1 = description1; this.description2 = description2; [Link] = nom; } protected String description() { if ((description1 != null) && (description2 != null)) return "Marque "+nom+" : "+description1+" "+description2; else if (description1 != null) return "Marque "+nom+" : "+description1; else return null; } } Enfin,laclasseUtilisateurreprsenteleprogrammeprincipal. public class Utilisateur { public static void main(String[] args) { ObjetBase vhicule1 = new Vhicule ( "Auto++ KT500 Vhicule doccasion en bon tat "); [Link]([Link]()); ObjetBase modle1 = new Modle("KT400", "Le vhicule spacieux et confortable"); ObjetBase vhicule2 = new Vhicule(null); [Link](modle1); [Link]([Link]()); ObjetBase marque1 = new Marque("Auto++", "La marque des autos","de grande qualit"); ObjetBase modle2 = new Modle("KT700",null); [Link](marque1); ObjetBase vhicule3 = new Vhicule(null); [Link](modle2); [Link]([Link]()); ObjetBase vhicule4 = new Vhicule(null); [Link]([Link]()); } } Lersultatdelexcutiondeprogrammeproduitlersultatsuivant. Auto++ KT500 Vhicule doccasion en bon tat Modle KT400 : Le vhicule spacieux et confortable Marque Auto++ : La marque des autos de grande qualit description par dfaut
- 2-
- 3-
Description
Le pattern Command a pour objectif de transformer une requte en un objet, facilitant des oprations comme lannulation,lamiseenfiledesrequtesetleursuivi.
- 1-
Exemple
Danscertainscas,lagestiondunecommandepeuttreassezcomplexe:ellepeuttreannulable,misedansunefile [Link],legestionnairepeutdemanderaucatalogue [Link],cette demandedoitpouvoirtreannulepuis,ventuellement,rtablie. Pour grer cette annulation, une premire solution consiste indiquer au niveau de chaque vhicule sil est ou non [Link]. Uneautresolutionseraitalorsdeconserversonprixavantladernireremise,maiscettesolutionnestpasnonplus satisfaisantecarlannulationpeutportersuruneautrerequtederemisequeladernire. Le pattern Command rsout ce problme en transformant la requte en un objet dont les attributs vont contenir les paramtres ainsi que lensemble des objets sur lesquels la requte a t applique. Dans notre exemple, il devient ainsipossibledannuleroudertablirunerequtederemise. [Link] paramtres (pourcentage et dureStock) ainsi que la liste des vhicules pour lesquels la remise a t applique (associationvhiculesSolds). Il faut noter que lensemble des vhicules rfrencs par CommandeSolder est un sousensemble de lensemble des vhiculesrfrencsparCatalogue. Lors de lappel de la mthode lance CommandeSolder, la commande passe en paramtre est excute puis elle est stockedansunordretelqueladernirecommandestockeseretrouveenpremireposition.
- 1-
Figure19.1LepatternCommandappliqulagestiondesremisesappliquesdesvhiculesdoccasion Le diagramme de la figure 19.2 montre un exemple de squence dappels. Les deux paramtres fournis au constructeurdelaclasse CommandeSoldersontletauxderemiseetladureminimaledestockageexprimeenmois. Parailleurs,leparamtre ordredelamthode annuleCommandeSoldervautzropourladernirecommandeexcute, unpourlavantdernire,etc. Les interactions entre les instances de CommandeSolder et de Vhicule ne sont pas reprsentes dans un but de [Link],ilconvientdesereporteraucodeJavaprsentplusloin.
- 2-
Figure19.2Exempledesquencedesappelsdemthodesdudiagramme19.1
- 3-
Structure
[Link]
Lafigure19.3dtaillelastructuregnriquedupattern.
Figure19.3StructuredupatternCommand
[Link]
Lesparticipantsaupatternsontlessuivants:
q
Commandeestlinterfacequiintroduitlasignaturedelamthodelancequiexcutelacommande CommandeConcrte (CommandeSolder)implantelamthode lance,grelassociationavecleoulesrcepteurs etimplantelamthodestockeAnnulerquistockeltat(oulesvaleursncessaires)pourpouvoirannulerpar lasuite Client (Utilisateur)creetinitialiselacommandeetlatransmetlappelant Appelant (Catalogue)stockeetlancelacommande(mthodestockeLanceCommande)ainsiquventuellement lesrequtesdannulation
- 1-
Rcepteur (Vhicule)traitelesactionsncessairespoureffectuerlacommandeoupourlannuler.
[Link]
Lafigure19.4illustrelescollaborationsdupatternCommand:
q
Figure19.4CollaborationsauseindupatternCommand
- 2-
Domainesdapplication
Lepatternestutilisdanslescassuivants:
q
[Link],cestlappelantqui est paramtr par une commande qui contient la description dun traitement raliser sur un ou plusieurs rcepteurs les commandes doivent tre stockes dans une file et pouvoir tre excutes un moment quelconque, ventuellementplusieursfois lescommandessontannulables lescommandesdoiventtretracesdansunfichierdelog les commandes doivent tre regroupes sous la forme dune transaction. Une transaction est un ensemble ordonndecommandesquiagissentsurltatdunsystmeetquipeuventtreannules.
- 1-
ExempleenJava
Nous introduisons maintenant lexemple en Java. La classe Vhicule scrit en Java comme suit. Chaque vhicule possdeunnom,[Link] avecuncoefficient. public class Vhicule { protected String nom; protected long dateEntreStock; protected double prixVente; public Vhicule(String nom, long dateEntreStock, double prixVente) { [Link] = nom; [Link] = dateEntreStock; [Link] = prixVente; } public long getDureStockage(long aujourdhui) { return aujourdhui - dateEntreStock; } public void modifiePrix(double coefficient) { [Link] = 0.01 * [Link](coefficient * [Link] * 100); } public void affiche() { [Link](nom+" prix : "+prixVente+ " date entre Stock "+dateEntreStock); } } LaclasseCommandeSolderpossdelesattributssuivants:
q
Lamthode soldecalculedabordlesvhiculessolder,[Link],elle rtablitleprixdesvhiculessoldsenutilisantlinversedutauxderemiseinitial. import [Link].*; public class CommandeSolder { protected List<Vhicule> vhiculesSolds = new ArrayList<Vhicule>(); protected long aujourdhui; protected long dureStock; protected double tauxRemise; public CommandeSolder(long aujourdhui, long dureStock, double tauxRemise) { [Link] = aujourdhui; [Link] = dureStock;
- 1-
[Link] = tauxRemise; } public void solde(List<Vhicule> vhicules) { vhiculesSolds = new ArrayList<Vhicule>(); for (Vhicule vhicule : vhicules) if ([Link](aujourdhui) >= dureStock) [Link](vhicule); for (Vhicule vhicule : vhiculesSolds) [Link](1.0 - tauxRemise); } public void annule() { for (Vhicule vhicule : vhiculesSolds) [Link](1.0/(1.0 - tauxRemise)); } public void rtablit() { for (Vhicule vhicule : vhiculesSolds) [Link](1.0 - tauxRemise); } } LaclasseCataloguealecodesourceJavaquisuit. Elle gre la liste de tous les vhicules (attribut vhicules) ainsi que la liste des commandes (attribut commandes). Chaquenouvellecommandeestajouteaudbutdelalistedescommandescommelindiquelapremirelignedela mthodelanceCommandeSolder. import [Link].*; public class Catalogue { protected List<Vhicule> vhicules = new ArrayList<Vhicule>(); protected List<CommandeSolder> commandes = new ArrayList<CommandeSolder>(); public void lanceCommandeSolder(CommandeSolder commande) { [Link](0, commande); [Link](vhicules); } public void annuleCommandeSolder(int ordre) { [Link](ordre).annule(); } public void rtablitCommandeSolder(int ordre) { [Link](ordre).rtablit(); } public void ajoute(Vhicule vhicule) { [Link](vhicule); } public void affiche() { for (Vhicule vhicule : vhicules) [Link](); } }
- 2-
Enfin,[Link],deuxcommandesquisappliquentau premieretautroisimevhicule,lapremireappliquantuneremisede10%,lasecondeuneremisede50%.Laremise totale est de 55%, puis de 50% aprs lannulation de la premire remise, puis nouveau 55% aprs que cette premireremisesoitrtablie. public class Utilisateur { public static void main(String[] args) { Vhicule vhicule1 = new Vhicule("A01",1,1000.0); Vhicule vhicule2 = new Vhicule("A11",6,2000.0); Vhicule vhicule3 = new Vhicule("Z03",2,3000.0); Catalogue catalogue = new Catalogue(); [Link](vhicule1); [Link](vhicule2); [Link](vhicule3); [Link]("Affichage du catalogue initial"); [Link](); [Link](); CommandeSolder commmandeSolder = new CommandeSolder(10,5,0.1); [Link](commmandeSolder); [Link]("Affichage du catalogue aprs "+ "excution de la premire commande"); [Link](); [Link](); CommandeSolder commmandeSolder2 = new CommandeSolder(10,5,0.5); [Link](commmandeSolder2); [Link]("Affichage du catalogue aprs "+ "excution de la seconde commande"); [Link](); [Link](); [Link](1); [Link]("Affichage du catalogue aprs "+ "annulation de la premire commande"); [Link](); [Link](); [Link](1); [Link]("Affichage du catalogue aprs "+ "rtablissement de la premire commande"); [Link](); [Link](); } } Lexcutiondeceprogrammedonnelersultatsuivant. Affichage du catalogue A01 prix : 1000.0 date A11 prix : 2000.0 date Z03 prix : 3000.0 date initial entre Stock 1 entre Stock 6 entre Stock 2
Affichage du catalogue aprs excution de la premire commande A01 prix : 900.0 date entre Stock 1 A11 prix : 2000.0 date entre Stock 6 Z03 prix : 2700.0 date entre Stock 2 Affichage du catalogue aprs excution de la seconde commande A01 prix : 450.0 date entre Stock 1 A11 prix : 2000.0 date entre Stock 6 Z03 prix : 1350.0 date entre Stock 2 Affichage du catalogue aprs annulation de la premire commande A01 prix : 500.0 date entre Stock 1 A11 prix : 2000.0 date entre Stock 6
- 3-
Z03 prix : 1500.0 date entre Stock 2 Affichage du catalogue aprs rtablissement de la premire commande A01 prix : 450.0 date entre Stock 1 A11 prix : 2000.0 date entre Stock 6 Z03 prix : 1350.0 date entre Stock 2
- 4-
Description
Lepattern Interpreterfournituncadrepourdonnerunereprsentationparobjetsdelagrammairedunlangageafin dvaluer,enlesinterprtant,desexpressionscritesdanscelangage.
- 1-
Exemple
Nousvoulonscrerunpetitmoteurderecherchedesvhiculesbassurlarechercheparmotcldansladescription desvhiculeslaidedexpressionsboolennesselonlagrammairetrssimplesuivante: expression ::= terme || mot-cl || (expression) terme ::= facteur ou facteur facteur ::= expression et expression mot-cl ::= a..z,A..Z {a..z,A..Z}* [Link] expression, terme, [Link]. Nous mettons en uvre le pattern Interpreter afin de pouvoir exprimer toute expression rpondant cette grammaireselonunarbresyntaxiqueconstitudobjetsafindepouvoirlvaluerenlinterprtant. [Link],nousconsidronsquun motclconstitueun symboleterminalentantquechanedecaractres. Lexpression(rouge ou gris) et rcent et dieselvatretraduireparlarbresyntaxiquedelafigure20.1.
Figure20.1Arbresyntaxiquecorrespondantlexpression(rouge ou gris) et rcent et diesel [Link] udest unoprateur,lvaluationsefaitencalculantrcursivementlavaleurdechaquesousarbre(celuidegauchepuiscelui dedroite)[Link] udestunmotcl, lvaluationsefaitenrecherchantlachane correspondantedansladescriptionduvhicule. Le moteur de recherche consiste donc valuer lexpression pour chaque description et renvoyer la liste des vhiculespourlesquelslvaluationestvraie. Cettetechniquederecherchenestpasoptimise,ellenestdoncvalablequepourunepetitequantitde vhicules.
Lediagrammedesclassespermettantdedcriredesarbressyntaxiquescommeceluidelafigure20.1estreprsent la figure 20.2. La mthode value permet dvaluer lexpression pour une description dun vhicule fournie en
- 1-
paramtre.
Figure20.2LepatternInterpreterpourreprsenterdesarbressyntaxiquesetlesvaluer
- 2-
Structure
[Link]
Lafigure20.3dtaillelastructuregnriquedupattern. Cediagrammedeclassesmontrequilexistedeuxtypesdesousexpression,savoir:
q
leslmentsterminauxquipeuventtredesnomsdevariable,desentiers,desnombresrels les oprateurs qui peuvent tre binaires comme dans lexemple, unaires (oprateur ) ou prenant plus dargumentcommedesfonctions.
Figure20.3StructuredupatternInterpreter
[Link]
Lesparticipantsaupatternsontlessuivants:
q
Expression est une classe abstraite reprsentant tout type dexpression,cestdire tout n ud de larbre
ENI Editions - All rigths reserved - Algeria Educ - 1-
syntaxique
q
OprateurAbstrait (OprateurBinaire) est galement une classe abstraite. Elle dcrit tout n ud de type oprateur,cestdirepossdantdesoprandesquisontdessousarbresdelarbresyntaxique OprateurConcret1 et OprateurConcret2 (OprateurEt, OprateurOu) sont des implantations dOprateurAbstraitdcrivanttotalementlasmantiquedeloprateuretdonccapablesdelvaluer lmentTerminalestuneclasseabstraitedcrivanttoutn udcorrespondantunlmentterminal lmentTerminalConcret1 et lmentTerminalConcret2 (MotCl) sont des classes concrtes correspondant unlmentterminal,capablesdvaluercetlment.
[Link]
Leclientconstruituneexpressionsouslaformedunarbresyntaxiquedontlesn udssontdesinstancesdessous [Link]:
q
sicetteinstanceestunlmentterminal,lvaluationestdirecte si cette instance est un oprateur, il y a lieu de procder dabord lvaluation des oprandes. Cette valuationestfaitercursivement,chaqueoprandetantlesommetduneexpression.
- 2-
Domainesdapplication
[Link] principalementdanslescassuivants:
q
lagrammairedesexpressionsestsimple lvaluationnapasbesoindtrerapide.
Si la grammaire est complexe, il vaut mieux se tourner vers des analyseurs syntaxiques spcialiss. Si lvaluationdoittreeffectuerapidement,lutilisationduncompilateurpeutsavrerncessaire.
- 1-
ExempleenJava
NousfournissonslecodecompletdunexempleenJavaquinonseulementpermetlvaluationdunarbresyntaxique maisleconstruitgalement. Laconstructiondelarbresyntaxique,appeleanalysesyntaxique,estgalementrpartiedanslesclasses,savoir cellesdelafigure20.2souslaformedemthodesdeclasse(mthodesprfixesdumotclstaticenJava). Lecodesourcedelaclasse [Link] delasignaturedelamthodevalue. Lesmthodes prochainJeton, analyse,et [Link] analyseestutilise pourparseruneexpressionentirealorsque parseestddielanalysesoitdunmotclsoitduneexpressionmise entreparenthses. public abstract class Expression { protected abstract boolean value(String description); // partie analyse syntaxique static protected String source; static protected int index; static protected String jeton; static protected void prochainJeton() { while ((index < [Link]()) && ([Link](index) == )) index++; if (index == [Link]()) jeton = null; else if (([Link](index) == () || ([Link](index) == ))) { jeton = [Link](index, index+1); index++; } else { int dbut = index; while ((index < [Link]()) && ([Link](index) != ) && ([Link](index) != ))) index++; jeton = [Link](dbut,index); } } static public Expression analyse(String source) throws Exception { [Link] = source; index = 0; prochainJeton(); return [Link](); } static protected Expression parse() throws Exception { Expression rsultat; if ([Link]("(")) { prochainJeton(); rsultat = [Link](); if (jeton == null) throw new Exception("Erreur de syntaxe"); if (")) throw new Exception("Erreur de syntaxe"); prochainJeton(); } else rsultat = [Link]();
ENI Editions - All rigths reserved - Algeria Educ - 1-
return rsultat; } } [Link] MotCldont la mthode value recherche le motcl dans la description. Cette classe gre galement lanalyse syntaxique dun motcl. public class MotCl extends Expression { String motCl; MotCl(String motCl) { [Link] = motCl; } protected boolean value(String description) { return [Link](motCl) != -1; } // partie analyse syntaxique static protected Expression parse() throws Exception { Expression rsultat; rsultat = new MotCl(jeton); prochainJeton(); return rsultat; } } LaclasseabstraiteOprateurBinairegrelesliensverslesdeuxoprandesdeloprateur. public abstract class OprateurBinaire extends Expression { protected Expression oprandeGauche, oprandeDroite; public OprateurBinaire(Expression oprandeGauche, Expression oprandeDroite) { [Link] = oprandeGauche; [Link] = oprandeDroite; } } LaclasseconcrteOprateurOuimplantelamthodevalueetgrelanalysesyntaxiquedunterme. public class OprateurOu extends OprateurBinaire { public OprateurOu(Expression oprandeGauche, Expression oprandeDroite) { super(oprandeGauche,oprandeDroite); } public boolean value(String description) { return [Link](description) || [Link](description); } // partie analyse syntaxique static protected Expression parse() throws Exception { Expression rsultatGauche,rsultatDroit; rsultatGauche = [Link](); while ((jeton != null) && ([Link]("ou"))) { prochainJeton();
- 2-
rsultatDroit = [Link](); rsultatGauche = new OprateurOu(rsultatGauche, rsultatDroit); } return rsultatGauche; } } LaclasseconcrteOprateurEtimplantelamthodevalueetgrelanalysesyntaxiquedunfacteur. public class OprateurEt extends OprateurBinaire { public OprateurEt(Expression oprandeGauche, Expression oprandeDroite) { super(oprandeGauche,oprandeDroite); } public boolean value(String description) { return [Link](description) && [Link](description); } // partie analyse syntaxique static protected Expression parse() throws Exception { Expression rsultatGauche,rsultatDroit; rsultatGauche = [Link](); while ((jeton != null) && ([Link]("et"))) { prochainJeton(); rsultatDroit = [Link](); rsultatGauche = new OprateurEt(rsultatGauche, rsultatDroit); } return rsultatGauche; } } Enfin,laclasseUtilisateurimplanteleprogrammeprincipal. import [Link].*; public class Utilisateur { public static void main(String[] args) { Expression expressionRequte = null; Scanner reader = new Scanner([Link]); [Link]("Entrez votre requte : "); String requte = [Link](); try { expressionRequte = [Link](requte); } catch(Exception e) { [Link]([Link]()); expressionRequte = null; } if (expressionRequte != null) { [Link]("Entrez le texte de description dun"+ " vhicule : "); String description = [Link](); if ([Link](description)) [Link]("La description rpond la"+ " requte"); else [Link]("La description ne rpond pas la"+ " requte"); } } }
- 3-
Unexempledexcutionduprogrammesetrouvecidessous. Entrez votre requte : (rouge ou gris) et rcent et diesel Entrez le texte de description dun vhicule : Ce vhicule rouge fonctionnant au diesel est rcent La description rpond la requte
- 4-
Description
Le pattern Iterator fournit un accs squentiel une collection dobjets des clients sans que ceuxci doivent se proccuperdelimplantationdecettecollection.
- 1-
Exemple
Nous voulons donner un accs squentiel aux vhicules composant le catalogue. Pour cela, nous pouvons implanter danslaclasseducataloguelesmthodessuivantes:
q
Cettetechniqueprsentedeuxinconvnients:
q
Le pattern Iterator propose une solution ce problme. Lide est de crer une classe Itrateur dont chaque [Link] decollectionquisechargedelesinitialiser. Le but du pattern Iterator est de fournir une solution qui puisse tre paramtre par le type des lments des [Link]:
q
Ilestensuitepossibledecrerlessousclassesconcrtesdecesdeuxclassesabstraitesgnriques,sousclassesqui lientnotammentlesparamtresdegnricitauxtypesutilissdanslapplication. Lafigure21.1montrelutilisationdupattern Iteratorpourparcourirlesvhiculesducataloguequirpondentune requte. Cediagrammedeclassesutilisedesparamtresgnriquesquisontcontraints( Tlmentestunsoustypedelment et TItrateur est un soustype de Itrateur<Tlment>). Les deux classes Catalogue et Itrateur possdent une associationavecunensembledlments,lensembledeslmentsrfrencsparItrateurtantunsousensemble deceuxrfrencsparCatalogue. Lessousclasses CatalogueVhiculeetItrateurVhiculehritentparunerelationquifixelestypesdesparamtres degnricitdeleurssurclassesrespectives(strotypebind).
- 1-
Figure21.1LepatternIteratorpouraccdersquentiellementdescataloguesdevhicules
- 2-
Structure
[Link]
Lafigure21.2dtaillelastructuregnriquedupattern,quiesttrsprochedudiagrammedesclassesdelafigure 21.1.
Figure21.2StructuredupatternIterator
[Link]
Lesparticipantsaupatternsontlessuivants:
q
Itrateur est la classe abstraite qui implante lassociation de litrateur avec les lments de la collection [Link] ItrateurConcret lmentConcret (ItrateurVhicule) est une sousclasse concrte de Itrateur qui lie Tlment
Collection (Catalogue)estlaclasseabstraitequiimplantelassociationdelacollectionavecleslmentset lamthodecreItrateur CollectionConcrte (CatalogueVhicule) est une sousclasse concrte de Collection qui lie Tlment lmentConcretetTItrateurItrateurConcret
- 1-
lmentestlaclasseabstraitedeslmentsdelacollection lmentConcret (Vhicule) est une sousclasse concrte de lment utilise par ItrateurConcret et CollectionConcrte.
[Link]
[Link].
- 2-
Domainesdapplication
Lepatternestutilisdanslescassuivants:
q
- 1-
ExempleenJava
NousprsentonslexempleenJavaduparcoursducataloguedevhiculeslaidedunitrateur. [Link] motClValidevrifielappartenancedunmotclladescription. public abstract class lment { protected String description; public lment(String description) { [Link] = description; } public boolean motClValide(String motCl) { return [Link](motCl) != -1; } } LasousclasseconcrteVhiculeintroduitunemthodeaffiche. public class Vhicule extends lment { public Vhicule(String description) { super(description); } public void affiche() { [Link]("Description du vhicule : "+description); } } Laclasse Itrateurintroduitlesmthodes dbut, suivant, item ainsi que la mthode setMotClRequte qui initialise litrateur. import [Link]; public abstract class Itrateur<Tlment extends lment> { protected String motClRequte; protected int index; List<Tlment> contenu; protected void setMotClRequte(String motClRequte, List<Tlment> contenu) { [Link] = motClRequte; [Link] = contenu; } public void dbut() { index = 0; int taille = [Link](); while ((index < taille) && (.motClValide(motClRequte))) index++; } public void suivant() { int taille = [Link]();
- 1-
index++; while ((index < taille) && (.motClValide(motClRequte))) index++; } public Tlment item() { if (index < [Link]()) return [Link](index); else return null; } } LasousclasseItrateurVhiculesecontentedelierTlmentVhicule. public class ItrateurVhicule extends Itrateur<Vhicule> { } LaclasseCataloguegrelattributcontenuquiestlacollectiondeslmentsetintroduitlamthoderecherchequicre, initialiseetretournelitrateur. Lamthode [Link],ilnestpaspossibledecreruneinstanceavecuntypequiestun paramtre de gnricit. Son implantation doit tre ralise dans une sousclasse qui lie le paramtre une classe concrte. import [Link].*; public abstract class Catalogue<Tlment extends lment, TItrateur extends Itrateur<Tlment> > { List<Tlment> contenu = new ArrayList<Tlment>(); protected abstract TItrateur creItrateur(); public TItrateur recherche(String motClRequte) { TItrateur rsultat = creItrateur(); [Link](motClRequte,contenu); return rsultat; } } LasousclasseconcrteCatalogueVhiculelieTlmentVhiculeetTItrateurItrateurVhicule. Elleintroduitdeuxlments:
q
public class CatalogueVhicule extends Catalogue <Vhicule,ItrateurVhicule> { public CatalogueVhicule() { [Link](new Vhicule("vhicule bon march")); [Link](new Vhicule("petit vhicule bon march")); [Link](new Vhicule("vhicule grande qualit")); } protected ItrateurVhicule creItrateur() { return new ItrateurVhicule(); } }
- 2-
Enfin, la classe Utilisateurintroduitleprogrammeprincipalquicrelecataloguedesvhiculesetunitrateurbas [Link],leprogrammeprincipalaffichelalistedesvhiculesretournspar litrateur. public class Utilisateur { public static void main(String[] args) { CatalogueVhicule catalogue = new CatalogueVhicule(); ItrateurVhicule itrateur = [Link] ("bon march"); Vhicule vhicule; [Link](); vhicule = [Link](); while (vhicule != null) { [Link](); [Link](); vhicule = [Link](); } } } Lexcutiondeceprogrammeproduitlersultatsuivant. Description du vhicule : vhicule bon march Description du vhicule : petit vhicule bon march
- 3-
Description
Lepattern Mediatorapourbutdeconstruireunobjetdontlavocationestlagestionetlecontrledesinteractions dansunensembledobjetssansqueseslmentsdoiventseconnatremutuellement.
- 1-
Exemple
La conception par objets favorise la distribution du comportement entre les objets du systme. Cependant, lextrme, cette distribution peut conduire un trs grand nombre de liaisons obligeant quasiment chaque objet [Link] [Link],[Link] nepeutpastravaillersanslesautresetlesystmedevientmonolithique,[Link] adapter et modifier le comportement dune petite partie du systme, il devient ncessaire de dfinir de nombreuses sousclasses. Les interfaces utilisateur dynamiques sont un bon exemple dun tel systme. Une modification de la valeur dun contrlegraphiquepeutconduiremodifierlaspectdautrescontrlesgraphiquescomme,parexemple:
q
Lapremirepossibilitestdoncdelierchaquecontrleauxcontrlesdontlaspectchangeenfonctiondesavaleur. Cettepossibilitprsentelesinconvnientscitscidessus. Lautrepossibilitestdemettreen [Link] [Link],ilprvientlobjetmdiateurqui se charge dinvoquer les mthodes adquates des autres contrles graphiques afin quils puissent raliser les modificationsncessaires. Dans notre systme de vente en ligne de vhicules, un emprunt peut tre demand pour acqurir un vhicule en [Link] [Link],toutunensembledecontrlesgraphiquesrelatifsaux [Link] choixportenouveausurunempruntsanscoemprunteur. [Link]:
q
Contrleestuneclasseabstraitequiintroduitleslmentscommunstouslescontrlesgraphiques PopupMenu, ZoneSaisie et Bouton sont les sousclasses concrtes de Contrle qui implantent les mthodes dessineetclic [Link] parinvocationdelamthodecontrleModifi.
- 1-
Figure22.1LepatternMediatorpourgrerunformulairededemandedemprunt Chaquefoisquelavaleurduncontrlegraphiqueestmodifie,lamthode [Link] mthode hrite de la classe abstraite Contrle invoque son tour la mthode contrleModifi de Formulaire (le mdiateur). Celleci invoque, son tour, les mthodes des contrles du formulaire pour raliser les actions ncessaires. [Link] change,lazonedesaisiedunomducoemprunteurestrespectivementafficheoumasqueselonquelavaleurdu contrlemenuCoemprunteurvaut"avec"ou"sans".
- 2-
Figure22.2ExempledesquencedutilisationdupatternMediator
- 3-
Structure
[Link]
Lafigure22.3dtaillelastructuregnriquedupattern.
Figure22.3StructuredupatternMediator
[Link]
Lesparticipantsaupatternsontlessuivants:
q
Mdiateurdfinitlinterfacedumdiateurpourlesobjetslment MdiateurConcret (Formulaire)implantelacoordinationentreleslmentsetgrelesassociationsavecles lments lment (Contrle) est la classe abstraite des lments qui introduit leurs attributs, associations et mthodescommunes lmentConcret1 et lmentConcret2 (PopupMenu, ZoneSaisie et Bouton) sont les classes concrtes des lmentsquicommuniquentaveclemdiateuraulieudecommuniqueraveclesautreslments.
[Link]
Les lments envoient des messages au mdiateur et en reoivent. Le mdiateur implante la collaboration et la coordinationentreleslments.
- 1-
Domainesdapplication
Lepatternestutilisdanslescassuivants:
q
unsystmeestformdunensembledobjetsbassurunecommunicationcomplexeconduisantassocierde nombreuxobjetsentreeux lesobjetsdunsystmesontdifficilesrutilisercarilspossdentdenombreusesassociationsavecdautres objets la modularit dun systme est mdiocre, obligeant dans le cas dune adaptation dune partie du systme criredenombreusessousclasses.
- 1-
ExempleenJava
Nous proposons de simuler la saisie dun formulaire laide dentres/sorties classiques en bouclant sur une saisie squentielledechaquecontrlejusqucequeleboutonOKsoitvalid(auclavier).Unmenupermetdechoisirsi lempruntsefaitavecousanscoemprunteur. LecodeJavadelaclasseContrlescritlasuite. public abstract class Contrle { protected String valeur=""; protected Formulaire directeur; protected String nom; public Contrle(String nom) { [Link] = nom; } public abstract void saisie(); public String getNom() { return nom; } public void setDirecteur(Formulaire directeur) { [Link] = directeur; } public String getValeur() { return valeur; } protected void modifi() { [Link](this); } } Lecodesourcedelasousclasse [Link],ellelitlavaleurdela zoneauclavier. import [Link].*; public class ZoneSaisie extends Contrle { Scanner reader = new Scanner([Link]); public ZoneSaisie(String nom) { super(nom); } public void saisie() { [Link]("Saisie de : "+nom); valeur = [Link](); modifi(); } } [Link] etencasderponsefavorable,invoquelamthodemodifipoursignalercetterponseaumdiateur. import [Link].*; public class Bouton extends Contrle
ENI Editions - All rigths reserved - Algeria Educ - 1-
{ Scanner reader = new Scanner([Link]); public Bouton(String nom) { super(nom); } public void saisie() { [Link]("Dsirez-vous activer le bouton "+nom+" ?"); String rponse = [Link](); if ([Link]("oui")) modifi(); } } Lamthode saisiedelasousclasse PopupMenu affiche toutes les options possibles puis demande lutilisateurson choixetencasdechangementdevaleur,lesignaleaumdiateureninvoquantlamthodemodifi. import [Link].*; public class PopupMenu extends Contrle { List<String> options = new ArrayList<String>(); Scanner reader = new Scanner([Link]);
public PopupMenu(String nom) { super(nom); } public void saisie() { [Link]("Saisie de : "+nom); [Link]("Valeur actuelle : "+valeur); for (int index = 0; index < [Link](); index++) [Link]("- "+index+" )"+[Link](index)); int choix = [Link](); if ((choix >= 0) && (choix <[Link]())) { boolean chang = !([Link]([Link](choix))); if (chang) { valeur = [Link](choix); modifi(); } } } public void ajouteOption(String option) { [Link](option); } } LaclasseFormulaireestprsentelasuiteetintroduitdeuxmthodesimportantes:
q
la mthode saisie fonctionne en bouclant sur la saisie de chaque contrle jusquau moment o lattribut enCoursdevientfaux la mthode contrleModifi demande la saisie des informations du coemprunteur si le contrle menuCoemprunteur change de valeur et prend la valeur "avec coemprunteur". Elle met galement faux la valeurdelattributenCourssileboutonOKestactiv.
- 2-
protected List<Contrle> contrles = new ArrayList<Contrle>(); protected List<Contrle> contrlesCoemprunteur = new ArrayList<Contrle>(); protected PopupMenu menuCoemprunteur; protected Bouton boutonOK; protected boolean enCours = true; public void ajouteContrle(Contrle contrle) { [Link](contrle); [Link](this); } public void ajouteContrleCoemprunteur(Contrle contrle) { [Link](contrle); [Link](this); } public void setMenuCoemprunteur(PopupMenu menuCoemprunteur) { [Link] = menuCoemprunteur; } public void setBoutonOK(Bouton boutonOK) { [Link] = boutonOK; } public void contrleModifi(Contrle contrle) { if ((contrle == menuCoemprunteur) && ([Link]().equals("avec coemprunteur"))) { for(Contrle lmentCoemprunteur: contrlesCoemprunteur) [Link](); } if (contrle == boutonOK) { enCours = false; } } public void saisie() { while (true) { for(Contrle contrle: contrles) { [Link](); if (!enCours) return; } } } } Enfin,laclasseUtilisateurcontientleprogrammeprincipalquieffectuelesactionssuivantes:
q
- 3-
lancementdelasaisieduformulaire.
public class Utilisateur { public static void main(String[] args) { Formulaire formulaire = new Formulaire(); [Link](new ZoneSaisie("Nom")); [Link](new ZoneSaisie("Prnom")); PopupMenu menu = new PopupMenu("Coemprunteur"); [Link]("sans coemprunteur"); [Link]("avec coemprunteur"); [Link](menu); [Link](menu); Bouton bouton = new Bouton("OK"); [Link](bouton); [Link](bouton); [Link]( new ZoneSaisie("Nom du coemprunteur")); [Link]( new ZoneSaisie("Prnom du coemprunteur")); [Link](); } } [Link]. Saisie de : Nom Martin Saisie de : Prnom Jean Saisie de : Coemprunteur Valeur actuelle : - 0 )sans coemprunteur - 1 )avec coemprunteur 1 Saisie de : Nom du coemprunteur Dupont Saisie de : Prnom du coemprunteur Henri Dsirez-vous activer le bouton OK ? oui
- 4-
Description
LepatternMementoapourbutdesauvegarderetderestaurerltatdunobjetsansenviolerlencapsulation.
- 1-
Exemple
Lorsdelachatenlignedunvhiculeneuf,leclientpeutchoisirdesoptionssupplmentairesquivonttreajoutes son chariot. Cependant, il existe des options incompatibles comme, par exemple, les siges sportifs qui sont incompatiblesaveclessigesencuiroulesaccoudoirs. Laconsquencedecetteincompatibilitestquesilesaccoudoirsonttchoisisetquensuitelessigessportifssont choisis,loptiondesaccoudoirsestretireduchariot. Nous dsirons ensuite ajouter une option dannulation de la dernire opration effectue dans le chariot. Retirer la dernireoptionajoutenestpassuffisantcarilfautaussiremettrelesoptionsprsentesetquionttretirespour [Link]. Parlasuite,noussouhaitonstendrecemcanismepourgrerunhistoriquedestatsduchariotetpouvoirrevenir [Link],danscecas,mmorisertouslestatssuccessifsduchariot. Pour prserver lencapsulation de lobjet reprsentant le chariot, une solution consisterait mmoriser ces tats [Link]. Lepattern [Link] [Link],lechariotcreunmmento,linitialiseavecsontat,retireles options incompatibles avec cette nouvelle option, procde lajout de cette nouvelle option et renvoie le mmento [Link]. Seullechariotpeutmmorisersontatdanslemmentoetyrestaureruntatprcdent:lemmentoestopaque visvisdesautresobjets. Le diagramme de classes correspondant est illustr la figure 23.1. Le chariot y est reprsent par la classe ChariotOption et le mmento par la classe Mmento. Ltat du chariot consiste en lensemble de ses liens avec les options choisies. Les options sont reprsentes par la classe OptionVhicule qui introduit une association rflexive pourdcrirelesoptionsincompatibles. Il convient de remarquer que les options forment un ensemble dinstances de la classe OptionVhicule. Cesinstancessontpartagespartousleschariots.
- 1-
Figure23.1LepatternMementopourgrerlestatsdunchariotdoptions
- 2-
Structure
[Link]
Lafigure23.2dtaillelastructuregnriquedupattern.
Figure23.2StructuredupatternMemento
[Link]
Lesparticipantsaupatternsontlessuivants:
q
Mmentoestlaclassedesmmentosquisontlesobjetsquimmorisentltatinternedesobjetsdorigine(ou unepartiedecettat).Lemmentopossdedeuxinterfaces:uneinterfacecompltedestineauxobjets doriginequioffrelapossibilitdemmoriseretrestaurerleurtatetuneinterfacerduitepourlesobjetsde gestiondeltatquinontpasledroitdaccderltatinternedesobjetsdorigine ObjetOrigine (ChariotOption) est la classe des objets qui crent un mmento pour mmoriser leur tat internequilspeuventgalementrestaurerpartirdunmmento Gestiontat est responsable de la gestion des mmentos et naccde pas ltat interne des objets dorigine.
[Link]
Une instance de Gestiontat demande un mmento lobjet dorigine par appel de la mthode creMmento, le sauvegardeetencasdebesoindannulationetderetourltatmmorisdanslemmento,letransmetnouveau lobjetdorigineparlamthodesetMmento.
- 1-
- 2-
Domainesdapplication
Le pattern est utilis dans le cas o ltat interne dun objet (totalement ou en partie) doit tre mmoris afin de pouvoirtrerestaurultrieurementsansquelencapsulationdecetobjetnedoivetrebrise.
- 1-
ExempleenJava
Nous commenons la prsentation de lexemple Java par le mmento. Celuici est dcrit par linterface Mmento et la classe [Link] gettatet settatdontlinvocationestrserveauseulchariot. Linterfaceestvide,ellenesertqudtermineruntypepourlesautresobjetsquidoiventrfrencerlemmentosans pouvoiraccderauxmthodesgettatetsettat. Lemmentostockeltatduchariotdoptionssavoirunelistequiestconstruiteparduplicatadelalistedesoptions duchariot. public interface Mmento { } import [Link]; import [Link]; public class MmentoImpl implements Mmento { protected List<OptionVhicule> options = new ArrayList<OptionVhicule>(); void settat(List<OptionVhicule> options) { [Link](); [Link](options); } List<OptionVhicule> gettat() { return options; } } La classe ChariotOption dcrit les chariots. La mthode ajouteOption procde bien la suppression des options [Link] initial, mmento qui est renvoy [Link] annule revient ltatsauvegarddansle [Link]. import [Link].*; public class ChariotOption { protected List<OptionVhicule> options = new ArrayList<OptionVhicule>(); public Mmento ajouteOption(OptionVhicule optionVhicule) { MmentoImpl rsultat = new MmentoImpl(); [Link](options); [Link](optionVhicule. getOptionsIncompatibles()); [Link](optionVhicule); return rsultat; } public void annule(Mmento mmento) { MmentoImpl mmentoImplInstance; try { mmentoImplInstance = (MmentoImpl)mmento; } catch (ClassCastException e) { return; } options = [Link](); } public void affiche() { [Link]("Contenu du chariot des options");
- 1-
for (OptionVhicule option : options) [Link](); [Link](); } } LaclasseOptionVhiculedcrituneoptiondevhiculeneuf. import [Link].*; public class OptionVhicule { protected String nom; protected List<OptionVhicule> optionsIncompatibles = new ArrayList<OptionVhicule>(); public OptionVhicule(String nom) { [Link] = nom; } public void ajouteOptionIncompatible(OptionVhicule optionIncompatible) { if () { [Link](optionIncompatible); [Link](this); } } public List<OptionVhicule> getOptionsIncompatibles() { return optionsIncompatibles; } public void affiche() { [Link]("option : "+nom); } } Enfinleprogrammeprincipalestintroduitparlaclasse [Link] [Link] [Link],ilannulecedernierajout. public class Utilisateur { public static void main(String[] args) { Mmento mmento; OptionVhicule option1 = new OptionVhicule("Siges en cuir"); OptionVhicule option2 = new OptionVhicule("Accoudoirs"); OptionVhicule option3 = new OptionVhicule("Siges sportifs"); [Link](option3); [Link](option3); ChariotOption chariotOptions = new ChariotOption(); [Link](option1); [Link](option2); [Link](); mmento = [Link](option3); [Link](); [Link](mmento); [Link](); } } Lersultatdelexcutionduprogrammeestlesuivant.
- 2-
Contenu du chariot des options option : Siges en cuir option : Accoudoirs Contenu du chariot des options option : Siges sportifs Contenu du chariot des options option : Siges en cuir option : Accoudoirs
- 3-
Description
Lepattern Observer a pour objectif de construire une dpendance entre un sujet et des observateurs de sorte que chaquemodificationdusujetsoitnotifieauxobservateursafinquilspuissentmettrejourleurtat.
- 1-
Exemple
Nous voulons mettre jour laffichage dun catalogue de vhicules en temps rel. Chaque fois que les informations relatives un vhicule sont modifies, nous voulons mettre jour laffichage de cellesci. Il peut y avoir plusieurs affichagessimultans. LasolutionprconiseparlepatternObserverconsistetablirunlienentrechaquevhiculeetsesvuespourquele [Link] figure24.1.
Figure24.1LepatternObserverappliqulaffichagedevhicules Lediagrammecontientlesquatreclassessuivantes:
q
Sujet est la classe abstraite qui introduit tout objet qui notifie dautresobjetsdesmodificationsdesontat interne [Link]: descriptionet prix Observateur est linterface de tout objet qui a besoin de recevoir des notifications de changement dtat provenantdesobjetsauprsdesquelsilsestpralablementinscrit VueVhicule est la sousclasse concrte dimplantation de Observateur dont les instances affichent les informationsdunvhicule.
- 1-
Lefonctionnementestlesuivant:chaquenouvellevuesinscritentantquobservateurauprsdesonvhiculelaide delamthode [Link],[Link] ci demande tous les observateurs de se mettre jour en invoquant leur mthode actualise. Dans la classe VueVhicule, cette dernire mthode appelle redessine. Ce fonctionnement est illustr la figure 24.2 par un diagrammedesquence.
Figure24.2DiagrammedesquencedtaillantlutilisationdupatternObserver
La solution mise en uvre par le pattern Observer est gnrique. En effet, tout le mcanisme dobservation est implant dans la classe Sujet et linterface Observateur qui peuvent avoir dautres sousclasses que Vhicule et VueVhicule.
- 2-
Structure
[Link]
Lafigure24.3dtaillelastructuregnriquedupattern.
Figure24.3StructuredupatternObserver
[Link]
Lesparticipantsaupatternsontlessuivants:
q
Sujet est la classe abstraite qui introduit lassociation avec les observateurs ainsi que les mthodes pour ajouterouretirerdesobservateurs Observateurestlinterfaceimplanterpourrecevoirdesnotifications(mthodeactualise) SujetConcret (Vhicule)[Link] tatestmodifi ObservateurConcret (VueVhicule) est une classe dimplantation dun observateur. Celuici maintient une [Link] partiedesontatlorsdesmisesjourparinvocationdelamthodegettat.
- 1-
[Link]
Le sujet concret notifie ses observateurs lorsque son tat interne est modifi. Lorsquun observateur reoit cette notification,[Link],ilpeutinvoquerdesmthodesdusujet donnantaccssontat.
- 2-
Domainesdapplication
Lepatternestutilisdanslescassuivants:
q
unemodificationdansltat dunobjetengendredesmodificationsdansdautres objets qui sont dtermins dynamiquement unobjetveutprvenirdautresobjetssansdevoirconnatreleurtype,cestdiresanstrefortementcoupl ceuxci onneveutpasfusionnerdeuxobjetsenunseul.
- 1-
ExempleenJava
[Link] sontgrslaideduneliste. import [Link].*; public abstract class Sujet { protected List<Observateur> observateurs = new ArrayList<Observateur>(); public void ajoute(Observateur observateur) { [Link](observateur); } public void retire(Observateur observateur) { [Link](observateur); } public void notifie() { for (Observateur observateur : observateurs) [Link](); } } LecodesourcedelinterfaceObservateuresttrssimplecarilnecontientquelasignaturedelamthodeactualise. public interface Observateur { void actualise(); } Lecodesourcedelaclasse [Link] [Link]. public class Vhicule extends Sujet { String description; Double prix; public String getDescription() { return description; } public void setDescription(String description) { [Link] = description; notifie(); } public Double getPrix() { return prix; } public void setPrix(Double prix) { [Link] = prix; notifie(); } } LaclasseVueVhiculegreuntextequicontientladescriptionetleprixduvhiculeassoci(lesujet).Cetexteestmis
- 1-
[Link]. public class VueVhicule implements Observateur { protected Vhicule vhicule; protected String texte = ""; public VueVhicule(Vhicule vhicule) { [Link] = vhicule; [Link](this); actualise(); } public void actualise() { texte = "Description "+[Link]()+ " Prix : "+[Link](); } public void affiche() { [Link](texte); } } Enfin, la classe Utilisateur introduit le programme principal. Celuici cre un vhicule puis une vue dont il demande laffichage. Le prix est ensuite modifi et la vue est raffiche. Puis une seconde vue est cre associe au mme [Link]. public class Utilisateur { public static void main(String[] args) { Vhicule vhicule = new Vhicule(); [Link]("Vhicule bon march"); [Link](5000.0); VueVhicule vueVhicule = new VueVhicule(vhicule); [Link](); [Link](4500.0); [Link](); VueVhicule vueVhicule2 = new VueVhicule(vhicule); [Link](5500.0); [Link](); [Link](); } } Lersultatdelexcutiondeceprogrammeestlasuite. Description Description Description Description Vhicule Vhicule Vhicule Vhicule bon bon bon bon march march march march Prix Prix Prix Prix : : : : 5000.0 4500.0 5500.0 5500.0
- 2-
Description
LepatternStatepermetunobjetdadaptersoncomportementenfonctiondesontatinterne.
- 1-
Exemple
[Link] [Link] [Link] EnCoursestltatolacommandeestencoursdeconstitution:leclientajoutedesproduits. Ltat Valide est ltat o la commande a t valide et rgle par le client. Enfin ltat Livre est ltat o les produitsonttlivrs.
Figure25.1Diagrammedtatstransitionsdunecommande La classe Commande possde des mthodes dont le comportement diffre en fonction de cet tat. Par exemple, la mthode ajouteProduitnajoutedesproduitsquesilacommandesetrouvedansltat EnCours. La mthode efface napasdecomportementdansltatLivre. Lapproche traditionnelle pour rsoudre ces diffrences de comportement consiste utiliser des conditions dans le [Link]. Le pattern State propose une autre solution qui consiste transformer chaque tat en une classe. Cette classe introduitlesmthodesdelaclasseCommandedpendantdestatsenleurconfrantlecomportementproprecettat. [Link] aux tats sont CommandeEnCours, CommandeValide et CommandeLivre. Elles sont sousclasses de la classe abstraite tatCommande qui dtient lassociation avec la classe Commande. La classe tatCommande introduit galement les signatures des mthodes dont le comportement dpend de ltat courant, mthodes implantes dans ses sous classes. Une instance de la classe Commande possde une rfrence vers une instance de la sousclasse dtatCommande qui [Link] Commande,lesmthodesquidpendentdeltatcourantdlguent leur invocation cette instance. La note relative la mthode ajouteProduit dans la figure 25.2 illustre cette dlgation.
- 1-
Figure25.2LepatternStateappliquauxtatsdunecommande
- 2-
Structure
[Link]
Lafigure25.3illustrelastructuregnriquedupattern.
Figure25.3StructuredupatternState
[Link]
Lesparticipantsaupatternsontlessuivants:
q
Machinetat (Commande)estuneclasseconcrtedcrivantdesobjetsquisontdesmachinestats,cest dire qui possdent un ensemble dtats pouvant tre dcrit par un diagramme dtatstransitions. Cette classemaintientunerfrenceversuneinstancedunesousclassedtatquidfinitltatcourant tat (tatCommande)estuneclasseabstraitequiintroduitlasignaturedesmthodesliesltatetquigre lassociationaveclamachinetats tatConcretAet tatConcretB (CommandeEnCours, CommandeValide et CommandeLivre) sont des sousclasses concrtesquiimplantentlecomportementdesmthodesrelativementchaquetat.
[Link]
Lamachinetatsdlguelesappelsdesmthodesdpendantdeltatcourantversunobjetdtat. La machine tats peut transmettre lobjet dtat une rfrence vers ellemme si cest ncessaire. Cette rfrencepeuttrepasselorsdechaquedlgationoulinitialisationdelobjetdtat.
- 1-
Domainesdapplication
Lepatternestutilisdanslecassuivant:
q
lecomportementdunobjetdpenddesontat limplantationdecettedpendanceltatpardesinstructionsconditionnellesesttropcomplexe.
- 1-
ExempleenJava
Nous prsentons lexemple de la figure 25.2 en Java. La classe Commande est dcrite la suite. Les mthodes ajouteProduit, retireProduitet effacedpendentdeltat. Par consquent leur implantation consiste appeler la mthodecorrespondantedelinstancerfrencepartatCommande. Le constructeur de la classe initialise lattribut tatCommande avec une instance de la classe CommandeEnCours. La mthodetatSuivantpasseltatsuivantenassociantunenouvelleinstancelattributtatCommande. import [Link].*; public class Commande { List<Produit> produits = new ArrayList<Produit>(); tatCommande tatCommande; public Commande() { tatCommande = new CommandeEnCours(this); } public void ajouteProduit(Produit produit) { [Link](produit); } public void retireProduit(Produit produit) { [Link](produit); } public void efface() { [Link](); } public void tatSuivant() { tatCommande = [Link](); } public List<Produit> getProduits() { return produits; } public void affiche() { [Link]("Contenu de la commande"); for (Produit produit : produits) [Link](); [Link](); } } Laclasseabstraite tatCommandegrelelienavecuneinstancede Commandeainsiquelasignaturedesmthodesde Commandequidpendentdeltat. public abstract class tatCommande { Commande commande; public tatCommande(Commande commande) { [Link] = commande; } public abstract void ajouteProduit(Produit produit);
- 1-
public abstract void efface(); public abstract void retireProduit(Produit produit); public abstract tatCommande tatSuivant(); } LasousclasseCommandeEnCoursimplantelesmthodesdtatCommandepourltatEnCours. public class CommandeEnCours extends tatCommande { public CommandeEnCours(Commande commande) { super(commande); } public void ajouteProduit(Produit produit) { [Link]().add(produit); } public void efface() { [Link]().clear(); } public void retireProduit(Produit produit) { [Link]().remove(produit); } public tatCommande tatSuivant() { return new CommandeValide(commande); } } LasousclasseCommandeValideimplantelesmthodesdtatCommandepourltatValide. public class CommandeValide extends tatCommande { public CommandeValide(Commande commande) { super(commande); } public void ajouteProduit(Produit produit) { } public void efface() { [Link]().clear(); } public void retireProduit(Produit produit) { } public tatCommande tatSuivant() { return new CommandeLivre(commande); } } Lasousclasse CommandeLivre implante les mthodes dtatCommande pour ltat Livre. Dans cet tat, le corps des mthodesestvide. public class CommandeLivre extends tatCommande { public CommandeLivre(Commande commande) { super(commande);
- 2-
} public void ajouteProduit(Produit produit) { } public void efface() { } public void retireProduit(Produit produit) { } public tatCommande tatSuivant() { return this; } } LaclasseProduitrfrenceparlaclasseCommandepossdelecodesourceJavasuivant. public class Produit { protected String nom; public Produit(String nom) { [Link] = nom; } public void affiche() { [Link]("Produit : "+nom); } } Le programme principal est introduit par la classe Utilisateur. Le programme cre deux commandes. Il efface la premire dans ltat Valide, ce qui conduit bien une remise zro. Quant la seconde, elle est efface par le programmeunefoisquellesetrouvedansltatLivre,cequineprovoquerien. public class Utilisateur { public static void main(String[] args) { Commande commande = new Commande(); [Link](new Produit("vhicule 1")); [Link](new Produit("Accessoire 2")); [Link](); [Link](); [Link](new Produit("Accessoire 3")); [Link](); [Link](); Commande commande2 = new Commande(); [Link](new Produit("vhicule 11")); [Link](new Produit("Accessoire 21")); [Link](); [Link](); [Link](); [Link](); [Link](); [Link](); } } Lexcutiondeceprogrammefournitdonclersultatsuivant. Contenu de la commande
- 3-
Produit : vhicule 1 Produit : Accessoire 2 Contenu de la commande Contenu de la commande Produit : vhicule 11 Produit : Accessoire 21 Contenu de la commande Produit : vhicule 11 Produit : Accessoire 21 Contenu de la commande Produit : vhicule 11 Produit : Accessoire 21
- 4-
Description
Lepattern Strategyapourobjectifdadapterlecomportementetlesalgorithmesdun objet en fonction dunbesoin sanschangerlesinteractionsdecetobjetaveclesclients. Cebesoinpeutreleverdeplusieursaspectscommedesaspectsdeprsentation,defficacitentempsouenmmoire, dechoixdalgorithmes,dereprsentationinterne,[Link],ilnesagitpasdunbesoinfonctionnelvis visdesclientsdelobjetcarlesinteractionsentrelobjetetsesclientsdoiventresterinchanges.
- 1-
Exemple
Dans le systme de vente en ligne de vhicules, la classe VueCatalogue dessine la liste des vhicules destins la vente. Un algorithme de dessin est utilis pour calculer la mise en page en fonction du navigateur. Il existe deux versionsdecetalgorithme:
q
unepremireversionquinaffichequunseulvhiculeparligne(unvhiculeprendtoutelalargeurdisponible) etquiaffichelemaximumdinformationsainsiquequatrephotos une seconde version qui affiche trois vhicules par ligne mais qui affiche moins dinformations et une seule photo.
Linterface de la classe VueCatalogue ne dpend pas du choix de lalgorithme de mise en page. Ce choix na pas [Link]. Unepremiresolutionconsistetransformerlaclasse VueCatalogueenuneinterfaceouenuneclasseabstraiteet introduire deux sousclasses dimplantation diffrant par le choix de lalgorithme. Ceci prsente linconvnient de complexifierinutilementlahirarchiedesvuesdecatalogue. Une autre possibilit est dimplanter les deux algorithmes dans la classe VueCatalogue et laide dinstructions [Link] mthodesestdifficileapprhender. Le pattern Strategy propose une autre solution en introduisant une classe par algorithme. Lensemble des classes ainsicrespossdeuneinterfacecommunequiestutilisepourdialogueraveclaclasseVueCatalogue.Lafigure26.1 montrelediagrammedesclassesdelapplicationdupatternStrategy. Ce diagramme montre les deux classes dalgorithmes : DessinUnVhiculeLigne et DessinTroisVhiculesLigne implantant linterface DessinCatalogue. Les notes dtaillant les deux mthodes de la classe VueCatalogue montrent commentcesdeuxclassessontutilises.
- 1-
Figure26.1ApplicationdupatternStrategypourledessindecataloguesdevhicules
- 2-
Structure
[Link]
Lafigure26.2montrelastructuregnriquedupattern.
Figure26.2StructuredupatternStrategy
[Link]
Lesparticipantsaupatternsontlessuivants:
q
Stratgie (DessinCatalogue)[Link] Entitpourinvoquerlalgorithme StratgieConcrteAet StratgieConcrteB (DessinUnVhiculeLigne et DessinTroisVhiculesLigne) sont les sousclassesconcrtesquiimplantentlesdiffrentsalgorithmes Entitest la classe utilisant un des algorithmes des classes dimplantation de Stratgie. En consquence, [Link],sincessaire,ellepeutexposer sesdonnesinternesauxclassesdimplantation.
[Link]
[Link] cas le plus simple, les donnes ncessaires lalgorithme sont transmises en paramtre. Si ncessaire, la classe Entitimplantedesmthodespourdonneraccssesdonnesinternes. Leclientinitialiselentitavecuneinstancedelaclassedimplantationde [Link] et,engnral,[Link]. Lentitredirigelesrequtesprovenantdesesclientsverslinstancerfrenceparsonattributstratgie.
- 1-
Domainesdapplication
Lepatternestutilisdanslescassuivants:
q
Danslederniercas,lepatternStrategypermetderegroupercesclassesenuneseule,cequisimplifielinterfacepour lesclients.
- 1-
ExempleenJava
Notre exemple en Java est bas sur laffichage du catalogue de vhicules, simul ici simplement avec des sorties lcran. LinterfaceDessinCatalogueintroduitlamthodedessinequiprendenparamtreunelistedinstancesdeVueVhicule. import [Link].*; public interface DessinCatalogue { void dessine(List<VueVhicule> contenu); } Laclasse DessinUnVhiculeLigneimplantelamthode dessineenaffichantchaquevhiculesuruneligne(impression dunsautdeligneaprslaffichagedunvhicule). import [Link].*; public class DessinUnVhiculeLigne implements DessinCatalogue { public void dessine(List<VueVhicule> contenu) { [Link]("Dessine les vhicules avec un vhicule "+ "par ligne"); for (VueVhicule vueVhicule : contenu) { [Link](); [Link](); } [Link](); } } LaclasseDessinTroisVhiculesLigneimplantelamthodedessineenaffichanttroisvhiculeparligne(impressiondun sautdeligneaprslaffichagedetroisvhicules). import [Link].*; public class DessinTroisVhiculesLigne implements DessinCatalogue { public void dessine(List<VueVhicule> contenu) { int compteur; [Link]("Dessine les vhicules avec trois vhicules "+ "par ligne"); compteur = 0; for (VueVhicule vueVhicule : contenu) { [Link](); compteur++; if (compteur == 3) { [Link](); compteur = 0; } else [Link](" "); } if (compteur != 0) [Link](); [Link](); } } LaclasseVueVhiculequidessineunvhiculepossdelecodesuivant.
- 1-
Ilconvientdenoterquelamthode dessinedeVueVhicule,danslecasdecettesimulation,estidentique pour un affichage sur une ligne et sur trois lignes, ce qui nest pas le cas dans la ralit duneinterface graphique.
public class VueVhicule { protected String description; public VueVhicule(String description) { [Link] = description; } public void dessine() { [Link](description); } } La classe VueCatalogue possde un constructeur qui prend comme paramtre une instance de lune des classes dimplantation de DessinCatalogue, instance qui est mmorise dans lattribut dessin. Ce constructeur initialise galementlecontenuquidevraittrenormalementludepuisunebasededonnes. [Link] verslecontenuducatalogue. import [Link].*; public class VueCatalogue { protected List<VueVhicule> contenu = new ArrayList<VueVhicule>(); protected DessinCatalogue dessin; public VueCatalogue(DessinCatalogue dessin) { [Link](new VueVhicule("vhicule bon march")); [Link](new VueVhicule("vhicule spacieux")); [Link](new VueVhicule("vhicule rapide")); [Link](new VueVhicule("vhicule confortable")); [Link](new VueVhicule("vhicule sportif")); [Link] = dessin; } public void dessine() { [Link](contenu); } } Enfin,leprogrammeprincipalestimplantparlaclasse [Link] VueCatalogue,la [Link]. Aprslesavoircrs,leprogrammeprincipalinvoquelamthodedessinedesesinstances. public class Utilisateur { public static void main(String[] args) { VueCatalogue vueCatalogue1 = new VueCatalogue(new DessinTroisVhiculesLigne()); [Link](); VueCatalogue vueCatalogue2 = new VueCatalogue(new DessinUnVhiculeLigne()); [Link](); } } Lexcution de ce programme produit le rsultat suivant, ce qui montre bien que le comportement de la mthode
- 2 ENI Editions - All rigths reserved - Algeria Educ
dessineestparamtrparlinstancetransmiseenparamtreauconstructeur. Dessine les vhicules avec trois vhicules par ligne vhicule bon march vhicule spacieux vhicule rapide vhicule confortable vhicule sportif Dessine les vhicules avec un vhicule par ligne vhicule bon march vhicule spacieux vhicule rapide vhicule confortable vhicule sportif
- 3-
Description
Lepattern Template Methodpermetdereporterdansdessousclassescertainestapesdelunedesoprationsdun objet,cestapestantalorsdcritesdanslessousclasses.
- 1-
Exemple
Au sein du systme de vente en ligne de vhicules, nous grons des commandes issues de clients en France et au [Link],letauxde TVAesttoujoursde19,6%,ilestvariableauLuxembourg(12%pourlapartiedesprestations,15%pourlematriel). LecalculdelaTVAdemandedeuxoprationsdecalculdistinctesenfonctiondupays. Une premire solution consiste implanter deux classes distinctes sans surclasse commune : CommandeFrance et CommandeLuxembourg. Cette solution prsente linconvnient majeur davoir du code identique mais qui na pas t factoriscommelaffichagedesinformationsdelacommande(mthodeaffiche). UneclasseabstraiteCommandepeuttreintroduitepourfactoriserlesmthodescommunescommelamthodeaffiche. Le pattern Template Method propose daller plus loin en proposant de factoriser du code commun au sein des [Link] de la mthode calculeMontantTtc dont lalgorithme est le suivant pour la France (enpseudocode). calculeMontantTtc : montantTva = montantHt * 0,196 ; montantTtc = montantHt + montantTva ; LalgorithmepourleLuxembourgestdonnparlepseudocodesuivant. calculeMontantTtc : montantTva = (montantPrestationHt * 0,12) + (montantMatrielHt * 0,15) ; montantTtc = montantHt + montantTva ; Nousvoyonssurcetexemplequeladernirelignedelamthodeestcommuneauxdeuxpays(danscetexemple,ilny aquunelignemaisdansuncasrel,lapartiecommuneestplusimportante). Nous remplaons la premire ligne par un appel dune nouvelle mthode appele calculeTva. Ainsi la mthode calculeMontantTtcestdcritedornavantainsi: calculeMontantTtc : calculeTva() ; montantTtc = montantHt + montantTva ; La mthode calculeMontantTtc peut maintenant tre factorise. Le code spcifique a t dplac dans la mthode calculeTva dont limplantation reste spcifique chaque pays. La mthode calculeTva est introduite dans la classe Commandeentantquemthodeabstraite. LamthodecalculeMontantTtcestappeleunemthode"patron"(templatemethod).Unemthode"patron"introduit lapartiecommunedunalgorithmequiestensuitecompltepardespartiesspcifiques. Cettesolutionestillustreparlediagrammedeclassesdelafigure27.1o,pourdesraisonsdesimplification,lecalcul delaTVAluxembourgeoiseatramenuntauxuniquede15%.
- 1-
Figure27.1ApplicationdupatternTemplate MethodpourlecalculdelaTVAdunecommandeenfonctiondupays Lorsquun client appelle la mthode calculeMontantTtc dune commande, celleci invoque la mthode calculeTva. Limplantationdecettemthodedpenddelaclasseconcrtedelacommande:
q
sicetteclasseest CommandeFrance,[Link] avecletauxde19,6% si cette classe est CommandeLuxembourg, le diagramme de squence est dcrit la figure 27.3. La TVA est calculeavecletauxde15%.
- 2-
Figure27.2DiagrammedesquenceducalculdumontantTTCdunecommandefranaise
- 3-
Figure27.3DiagrammedesquenceducalculdumontantTTCdunecommandeluxembourgeoise
- 4-
Structure
[Link]
Lafigure27.4montrelastructuregnriquedupattern.
Figure27.4StructuredupatternTemplate Method
[Link]
Lesparticipantsaupatternsontlessuivants:
q
La classe abstraite ClasseAbstraite (Commande)introduit la mthode "patron" ainsi que la signature des mthodesabstraitesquecettemthodeinvoque. La sousclasse concrte ClasseConcrte (CommandeFrance et CommandeLuxembourg) implante les mthodes abstraitesutilisesparlamthode"patron"[Link].
[Link]
Limplantationdelalgorithmeestraliseparlacollaborationentrelamthode"patron"delaclasseabstraiteetles mthodesdunesousclasseconcrtequicompltentlalgorithme.
- 1-
Domainesdapplication
Lepatternestutilisdanslescassuivants:
q
- 1-
ExempleenJava
La classe abstraite Commande introduit la mthode "patron" calculeMontantTtc qui invoque la mthode abstraite calculeTva. public abstract class Commande { protected double montantHt; protected double montantTva; protected double montantTtc; protected abstract void calculeTva(); public void calculeMontantTtc() { [Link](); montantTtc = montantHt +montantTva ; } public void setMontantHt(double montantHt) { [Link] = montantHt; } public void affiche() { [Link]("Commande"); [Link]("Montant HT "+montantHt); [Link]("Montant TTC "+montantTtc); } } LasousclasseconcrteCommandeFranceimplantelamthodecalculeTvaavecletauxdeTVAfranais. public class CommandeFrance extends Commande { protected void calculeTva() { montantTva = montantHt*0.196; } } LasousclasseconcrteCommandeLuxembourgimplantelamthodecalculeTvaavecletauxdeTVAluxembourgeois. public class CommandeLuxembourg extends Commande { protected void calculeTva() { montantTva = montantHt*0.15; } } Enfinlaclasse [Link],enfixelemontant HT, calcule le montant TTC puis affiche la commande. Ensuite, le programme principal fait la mme chose avec une commandeluxembourgeoise. public class Utilisateur { public static void main(String[] args) { Commande commandeFrance = new CommandeFrance(); [Link](10000); [Link](); [Link](); Commande commandeLuxembourg = new CommandeLuxembourg();
- 1-
[Link](10000); [Link](); [Link](); } } Lexcutionduprogrammefournitlersultatsuivant. Commande Montant HT 10000.0 Montant TTC 11960.0 Commande Montant HT 10000.0 Montant TTC 11500.0
- 2-
Description
[Link] peuventainsitreajoutessansmodifierlesclassesdecesobjets.
- 1-
Exemple
Considronslafigure28.1quidcritlesclientsdenotresystmeorganisssouslaformedobjetscompossselonle pattern Composite. lexception de la mthode ajouteFililale spcifique la gestion de la composition, les deux sousclassespossdentdeuxmthodesdemmenom: [Link] cesmthodescorrespondunemmefonctionnalitmaisdontlimplantationestbiensradapteenfonctiondela [Link],lecalculdu chiffredaffairesdunclient(filialesinclusesounon),etc. Sur le diagramme, le calcul du cot de lentretien nest pas dtaill. Le dtail se trouve dans le chapitre consacraupatternComposite.
Cette approche est utilisable tant que le nombre de fonctionnalits reste faible. En revanche, si celuici devient important,nousobtenonsalorsdesclassescontenantbeaucoupdemthodes,difficilesapprhenderetmaintenir. De surcrot, ces fonctionnalits donnent lieu des mthodes (calculeCotEntretienet envoieEmailCommercial)sans lienentreellesetsanslienaveclec urdesobjetsladiffrence,parexemple,delamthode ajouteFililalequi contribuecomposerlesobjets.
Figure28.1Fonctionnalitsmultiplesauseindobjetscomposs Le pattern Visitor propose dimplanter les nouvelles fonctionnalits dans un objet spar appel visiteur. Chaque visiteur tablit une fonctionnalit pour plusieurs classes en introduisant pour chacune de ces classes une mthode dimplantationdontlenomrespecteuneconventiondenommageunique,savoirvisitesuividunomdelaclasse. Ensuite,levisiteuresttransmislamthode [Link] [Link] classes,seulelamthode [Link] daccderlastructureinternedelobjetvisit(deprfrencepardesaccesseursenlecturecommeicilesmthodes getEmailetgetAdresse).
- 1-
Si les objets sont composs alors leur mthode accepteVisiteur appelle la mthode accepteVisiteur de leurs [Link] SocitMrequiappellelamthode accepteVisiteurde sesfiliales. Lediagrammedeclassesdelafigure28.2illustrelamiseen [Link] signature des mthodes implantant les fonctionnalits pour chaque classe visiter. Cette interface possde deux sousclassesdimplantation,uneparfonctionnalit.
Figure28.2ApplicationdupatternVisitorpourlajoutdunefonctionnalitdemailing
- 2-
Structure
[Link]
Lafigure28.3dtaillelastructuregnriquedupattern.
Figure28.3StructuredupatternVisitor
[Link]
Lesparticipantsaupatternsontlessuivants:
q
Visiteurestlinterfacequiintroduitlasignaturedesmthodesquiralisentunefonctionnalitauseindun ensemble de classes. Il existe une mthode par classe qui reoit comme argument une instance de cette classe. VisiteurConcret1 et VisiteurConcret2 (VisiteurCalculeCotEntretien et VisiteurMailingCommercial) implantent les mthodes qui ralisent la fonctionnalit correspondant la classe. Cette fonctionnalit est distribuedanslesdiffrentslments. lment (Socit) est une classe abstraite surclasse des classes dlments. Elle introduit la mthode abstraiteaccepteVisiteurquiaccepteunvisiteurcommeargument. lmentConcret1 et lmentConcret2 (SocitSansFiliale et SocitMre) implantent la mthode
ENI Editions - All rigths reserved - Algeria Educ - 1-
accepteVisiteurquiconsisterappelerlevisiteurautraversdelamthodecorrespondantlaclasse.
[Link]
Un client qui utilise un visiteur doit dabord le crer comme instance de la classe de son choix puis le transmettre commeargumentdelamthodeaccepteVisiteurdunensembledlments. [Link] argumentafinquelevisiteurpuisseaccdersastructureinterne.
- 2-
Domainesdapplication
Lepatternestutilisdanslescassuivants:
q
Si la structure de lensemble des classes auxquelles il est ncessaire dadjoindre des fonctionnalits changesouvent,lepattern [Link],toutemodificationdelastructureimplique unemodificationdechaquevisiteur,cequipeutcotercher.
- 1-
ExempleenJava
Nous reprenons lexemple de la figure 28.2. La classe Socit est dcrite en Java comme suit. La mthode accepteVisiteurestabstraitecarsoncodedpenddelasousclasse. public abstract class Socit { protected String nom, email, adresse; public Socit(String nom, String email, String adresse) { [Link] = nom; [Link] = email; [Link] = adresse; } public String getNom() { return nom; } public String getEmail() { return email; } public String getAdresse() { return adresse; } public abstract boolean ajouteFiliale(Socit filiale); public abstract void accepteVisiteur(Visiteur visiteur); } [Link] accepteVisiteurrappellelamthode VisiteSocitSansFililaleduvisiteur. public class SocitSansFiliale extends Socit { public SocitSansFiliale(String nom, String email, String adresse) { super(nom, email, adresse); } public void accepteVisiteur(Visiteur visiteur) { [Link](this); } public boolean ajouteFiliale(Socit filiale) { return false; } } Le code source de la sousclasse SocitMre est le suivant. La mthode accepteVisiteur rappelle la mthode VisiteSocitMreduvisiteurpuiselleinvoquelamthodeaccepteVisiteurdesesfiliales. import [Link]; import [Link]; public class SocitMre extends Socit
- 1-
{ protected List<Socit> filiales = new ArrayList<Socit>(); public SocitMre(String nom, String email, String adresse) { super(nom, email, adresse); } public void accepteVisiteur(Visiteur visiteur) { [Link](this); for (Socit filiale : filiales) [Link](visiteur); } public boolean ajouteFiliale(Socit filiale) { return [Link](filiale); } } LinterfaceVisiteurintroduitlasignaturedesdeuxmthodes,uneparclassedevanttrevisite. public interface Visiteur { void VisiteSocitSansFiliale(SocitSansFiliale socit); void VisiteSocitMre(SocitMre socit); } Laclasse VisiteurMailingCommercialenvoielesmailingsauxsocitsenimplantantlinterface [Link] possdant des filiales reoivent une proposition particulire et de surcrot par courrier. Ici le tout est simul par des impressionslcran. public class VisiteurMailingCommercial implements Visiteur { public void VisiteSocitSansFiliale(SocitSansFiliale socit) { [Link]("Envoi dun email "+[Link]()+ " adresse : "+[Link]()+ " Proposition commerciale pour votre socit"); } public void VisiteSocitMre(SocitMre socit) { [Link]("Envoi dun email "+[Link]()+ " adresse : "+[Link]()+ " Proposition commerciale pour votre groupe"); [Link]("Envoi dun courrier "+[Link]()+ " adresse : "+[Link]()+ " Proposition commerciale pour votre groupe"); } } Enfinlaclasse Utilisateurcreungroupe(groupe2)constitudelasocit3etdugroupe1,luimmeconstitude lasocit1etdelasocit2. Elleprocdeensuitelenvoidumailingtouteslessocitsdugroupe2eninvoquantsamthode accepteVisiteur avecunvisiteur,instancedelaclasseVisiteurMailingCommercial. public class Utilisateur {
- 2-
public static void main(String[] args) { Socit socit1 = new SocitSansFiliale("socit1", "info@[Link]","rue de la socit 1"); Socit socit2 = new SocitSansFiliale("socit2", "info@[Link]","rue de la socit 2"); Socit groupe1 = new SocitMre("groupe1", "info@[Link]","rue du groupe 1"); [Link](socit1); [Link](socit2); Socit socit3 = new SocitSansFiliale("socit3", "info@[Link]","rue de la socit 3"); Socit groupe2 = new SocitMre("groupe2","info@[Link]", "rue du groupe 2"); [Link](groupe1); [Link](socit3); [Link](new VisiteurMailingCommercial()); } } Lersultatdelexcutionestlesuivant. Envoi dun email groupe2 adresse : info@[Link] Proposition commerciale pour votre groupe Envoi dun courrier groupe2 adresse : rue du groupe 2 Proposition commerciale pour votre groupe Envoi dun email groupe1 adresse : info@[Link] Proposition commerciale pour votre groupe Envoi dun courrier groupe1 adresse : rue du groupe 1 Proposition commerciale pour votre groupe Envoi dun email socit1 adresse : info@[Link] Proposition commerciale pour votre socit Envoi dun email socit2 adresse : info@[Link] Proposition commerciale pour votre socit Envoi dun email socit3 adresse : info@[Link] Proposition commerciale pour votre socit
- 3-
Modlisationetconceptionaveclespatternsdeconception
Danscetouvrage,nousavonstudilespatternsdeconceptionautraversdeleurmiseen uvredansdesexemples. Ces patterns facilitent la conception en offrant des solutions solides des problmes connus. Ces solutions sont basessurunearchitecturequirespectelesbonnespratiquesdelaprogrammationparobjets. Dans lanalyse dun nouveau projet, ltape de dcouverte des objets et de leur modlisation ne ncessite pas [Link] reprsentant les objets du domaine. Ces objets sont issus de la modlisation, ils ne sont pas destins rsoudre [Link],cesobjets sont les vhicules, les constructeurs, les clients, le vendeur, les fournisseurs, les commandes, les factures, etc. La figure29.1montreunepartiedecettemodlisation,savoirlediagrammedeclassesdesvhicules.
Figure29.1Diagrammedeclassesdesvhicules [Link],ilfautimplanterlesfonctionnalitsdusystme,ce qui ncessite de nouveaux objets. la diffrence des objets du domaine, ces objets sont purement techniques et spcialissdanslaralisationdesfonctionnalits. Prenons dabord lexemple du catalogue en ligne des vhicules disponibles la vente. Limplantation de cette fonctionnalit ncessite lintroduction dun objet technique VueVhicule charg de dessiner un vhicule avec ses [Link] rafrachissement lcran, nous adoptons le pattern Observer comme lillustre lexemple du chapitre Le pattern Observer. [Link] dun systme. Si nous voulons rendre les aspects fonctionnels indpendants des familles de vhicules (vhicules
- 1-
Figure29.2Diagrammedtatstransitionsdunecommande [Link] montre comment un objet complmentaire qui reprsente ltat peut tre associ la commande. Cet objet sert adapterlecomportementdelamthodeenfonctiondesontatinterne.
- 2-
Autresapportsdespatternsdeconception
[Link]
Comme les classes, les patterns de conception constituent des abstractions. Mais la diffrence des classes, les [Link],nouslesavonsreprsentspar une structure constitue dun diagramme de classes complt par des explications sur les participations et sur les [Link],dcrireetclassifier [Link],lorsdelaconceptiondunsystme,ilestpossible dvoquerlutilisationdunpatternparsonnom,cequirenvoieunestructureconnue.
[Link]
Il est tout fait possible de concevoir des systmes sans utiliser les patterns de conception. Mais aprs quelques temps,[Link] ouvragesurlesujetconstitueungaindetempsetpermetdviterlesventuelscueilsdutilisation.
[Link]
Les patterns de conception possdent galement un aspect pdagogique : ils fournissent un dbutant un [Link] en uvrelesprincipesdelapprocheobjetscommelesassociationsentreobjets,lepolymorphisme,lesinterfaces, lesclassesetlesmthodesabstraites,ladlgation,laparamtrisation.
- 1-
noncsdesexercices
[Link]
[Link]
Lesclientsdunebanquesontclasssendeuxcatgories:
q
ceuxquiontledroitaucrdit ceuxquinontpascedroit.
Lors de la demande dune carte de paiement, les premiers reoivent une carte de crdit ( dbit diffr sur leur compte)alorsquelessecondspeuventseulementavoirunecartededbit(dbitimmdiatsurleurcompte). [Link]? [Link].
[Link]
Ilexistedeuxmodlesdecartesdedbitetdecrdit,savoirlescartesVisaetlescartesMasterCard. Modlisez, laide dun diagramme de classes, la cration dune carte de paiement en fonction de sa famille (de crditoudedbit)enutilisantlepatternAbstract Factory.
[Link]
Lorsdunachatavecunecartedepaiement,[Link] (dbitimmdiat),[Link] carteestunecartedecrdit(dbitdiffr),lautorisationestaccordesilemontantmensueldesdpensesnapas dpassleplafond. 1. Quel pattern de conception permetil de modliser lautorisation lors dun achat avec une carte de paiement en fonctiondumodledelacarte? [Link].
[Link]
[Link] rpertoires et de fichiers contenus dans un rpertoire "racine". Les fichiers et les rpertoires appartiennent un utilisateur. [Link]? [Link]. [Link] derpertoiresainsiquelatailleglobaledusystmedefichiers(lesdeuxcalculsdoiventtrespars). 3. Quel pattern permetil de calculer ces informations en modifiant au minimum le diagramme des classes de la question2? 4.Intgrezcepatterndanslediagrammedeclassesdelaquestion2. 5. Programmez ce diagramme de classes en Java en simulant laide dobjets les fichiers et les rpertoires. Le
ENI Editions - All rigths reserved - Algeria Educ - 1-
programme principal devra construire un exemple de systme de fichiers et calculer le nombre de fichiers et de rpertoiresdecetexempleainsiquesatailleglobale.
[Link]
Unbrowsergraphiquepermetdafficherdiffrentsobjetsdansunefentrecommeillustrcidessous.
Surcettefigure,troistypesdobjetssontprsents:
q
lesutilisateursreprsentsparunpersonnage lesrondsetlesovalesreprsentsparunicnerondouovale.
[Link]
[Link],puisintgrelavieactive puisprendsaretraite. [Link],ellenecotisepoursaretraitequelorsde [Link]. [Link]? [Link] getNom [Link]. LamthodeajoutePointsajoutedespointsderetraite. [Link] foisquedesdonnesdelapersonneoudesontatsontchanges,lesdonnesaffichesdanslinterfacegraphique [Link].
- 2-
[Link]? 4.Concevezlediagrammedeclassescorrespondantenintgrantlediagrammedelaquestion2.
[Link]
Laclasse [Link] mthodes:
q
Lamthode ajouterenvoietruesilajoutaputreralis,[Link] silobjetnapastretrouvdansledictionnaire. La classe DictPersistant est gnrique et prend comme argument le type des objets stocker. Elle implante linterfaceDictPersistantIntf,ellemmegnrique: Public interface DictPersistantIntf<T extends Object> { public boolean ajoute(String cl,T objet); public T get(String cl); } LecodesourcedeDictPersistantestlesuivant: import [Link].*; public class DictPersistant<T extends Object> implements DictPersistantIntf<T> { public boolean ajoute(String cl,T objet) { try { File fichierSortie = new File(cl); if ([Link]()) { FileOutputStream streamSortie= new FileOutputStream(fichierSortie); ObjectOutputStream streamObjet = new ObjectOutputStream(streamSortie); [Link](objet); [Link](); [Link](); return true; } } catch (IOException e) { return false; } return false; } @SuppressWarnings({ "unchecked"}) public T get(String cl) { try { File fichierLecture = new File(cl); if ([Link]()) { T rsultat; FileInputStream streamLecture = new FileInputStream(fichierLecture); ObjectInputStream streamObjet = new ObjectInputStream(streamLecture);
- 3-
try { rsultat = (T)[Link](); } catch (ClassNotFoundException e) { rsultat = null; } [Link](); return rsultat; } } catch (IOException e) { return null; } return null; } } Chaquefoisquunclientaccdeunobjetautraversdelamthodeget,[Link] lesclientsfontdesaccsfrquents,[Link] cacheconserveenmmoirelesobjetsdjchargsouceuxquionttajoutslorsdunesession. ImplantezceproxyenJavaenrespectantlepatternProxy.
- 4-
Correctiondesexercices
[Link]
[Link]
1. Le pattern adapt pour crer une carte en fonction du client est le pattern Factory Method. La cration de la carteestralisedanslasousclassecorrespondantlanatureduclient. [Link].
[Link]
LebutesticidobtenirunefabriquedecartesMasterCardetVisapourlescartesdecrditetunefabriquesimilaire [Link].
- 1-
[Link]
[Link] Template [Link] [Link] autorisePaiementestabstraitedanslaclasse [Link] danslesdeuxsousclassesCarteCrditetCarteDbitrelativementlnonc. [Link]:
- 2-
[Link]
[Link] du pattern Composite est totalement adaptepourmodliseruntelsystme. [Link] compos de n uds qui peuvent tre soit des fichiers soit des rpertoires. Le diagramme montre galement la relationentrelesystmedesfichiersetlerpertoire"racine".
- 3-
[Link] [Link]. [Link],la mthode accepteVisiteur a t introduite dans les classes Noeud, Fichier, Rpertoire et SystmeFichier. La mthode accepteVisiteur de SystmeFichier invoque la mthode accepteVisiteur de la racine. Cette dernire invoque la mthode visiteRpertoire du visiteur puis la mthode accepteVisiteur de chaque n ud. Ce [Link] ontuncomportementdiffrent:laclasseVisiteurNombrecomptelenombredefichiersetderpertoirestandisquela classeVisiteurTaillecomptelatailleglobaleoccupeparlesystmedefichiers.
- 4-
- 5-
[Link] Testintroduitunprogrammedetest. Celuicicreunsousrpertoiredelaracinequicontientdeuxfichiersdetaille100et200puiscreauniveaudela racinetroisfichiersdetaille1000,[Link],lenombredefichiersde troisetlatailletotalede6300commelemontrelexcutionduprogrammeprincipal. public abstract class Noeud { protected Utilisateur utilisateur; public Noeud(Utilisateur utilisateur) { [Link] = utilisateur; } public abstract boolean ajouteNoeud(Noeud noeud); public abstract void accepteVisiteur(VisiteurNoeud visiteur); } public class Fichier extends Noeud { protected int taille; public Fichier(Utilisateur utilisateur,int taille) { super(utilisateur); [Link] = taille; } public int getTaille() { return taille; } public void accepteVisiteur(VisiteurNoeud visiteur) { [Link](this); } public boolean ajouteNoeud(Noeud noeud) { return false; } } import [Link].*; public class Rpertoire extends Noeud
- 6-
{ protected List<Noeud> noeuds = new ArrayList<Noeud>(); public Rpertoire(Utilisateur utilisateur) { super(utilisateur); } public void accepteVisiteur(VisiteurNoeud visiteur) { [Link](this); for (Noeud noeud : noeuds) { [Link](visiteur); } } public boolean ajouteNoeud(Noeud noeud) { return [Link](noeud); } } public class Utilisateur { protected String nom; public Utilisateur(String nom) { [Link] = nom; } public String getNom() { return nom; } } public class SystmeFichier { protected Rpertoire racine; public SystmeFichier(Rpertoire racine) { [Link] = racine; } public void accepteVisiteur(VisiteurNoeud visiteur) { [Link](visiteur); } } public abstract class VisiteurNoeud { public abstract void visiteFichier(Fichier fichier); public abstract void visiteRpertoire(Rpertoire rpertoire); } public class VisiteurNombre extends VisiteurNoeud { protected int nombreFichiers = 0; protected int nombreRpertoires = 0; public void visiteFichier(Fichier fichier) { nombreFichiers = nombreFichiers + 1;
- 7-
} public void visiteRpertoire(Rpertoire rpertoire) { nombreRpertoires = nombreRpertoires + 1; } public int getNombreFichiers() { return nombreFichiers; } public int getNombreRpertoires() { return nombreRpertoires; } } public class VisiteurTaille extends VisiteurNoeud { int tailleTotale= 0; public void visiteFichier(Fichier fichier) { tailleTotale = tailleTotale + [Link](); } public void visiteRpertoire(Rpertoire rpertoire) { } public int getTailleTotale() { return tailleTotale; } } public class Test { public static void main(String[] args) { Utilisateur moiMme = new Utilisateur("moi mme"); Rpertoire racine = new Rpertoire(moiMme); Rpertoire rep = new Rpertoire(moiMme); [Link](rep); [Link](new Fichier(moiMme,100)); [Link](new Fichier(moiMme,200)); [Link](new Fichier(moiMme,1000)); [Link](new Fichier(moiMme,2000)); [Link](new Fichier(moiMme,3000)); SystmeFichier systmeFichier = new SystmeFichier(racine); VisiteurNombre visiteurNombre = new VisiteurNombre(); [Link](visiteurNombre); [Link]("Nombre de fichiers du systme de fichiers : " +[Link]()); [Link]("Nombre de rpertoires du systme de fichiers : " +[Link]()); VisiteurTaille visiteurTaille = new VisiteurTaille(); [Link](visiteurTaille); [Link]("Taille du systme de fichiers : " +[Link]()); } } Nombre de fichiers du systme de fichiers : 5 Nombre de rpertoires du systme de fichiers : 2 Taille du systme de fichiers : 6300
- 8-
[Link]
[Link] [Link] nombreuxobjetsdegrainfinestlepatternFlyweight. 2. Le diagramme de classes du browser est illustr la suite. Le browser est constitu dun ensemble dobjets, chacun tant li, lors de sa cration, un icne partag. Ltat intrinsque des icnes est constitu de la bitmap. Ltatextrinsqueestconstituparlesdeuxparamtresdelamthodedessine,savoir pointet [Link] paramtredonnelendroitoilfautdessinerlicneetlesecondletitreimprimersouslicne.
[Link]
[Link] [Link]. [Link] ajoutePoints qui ajoute des points de retraite ne possde un comportement que dans la vie active. Elle utilise la mthode setPointsRetraitedelaclassePersonnedontlusageestrservlaclassetatetsessousclasses.
ENI Editions - All rigths reserved - Algeria Educ - 9-
[Link] [Link] delutiliserdanslecadredecetexercice. [Link] Observeretintgrantlediagrammeprcdentsetrouvelasuite. La mthode ajoutePoints de la classe Actif invoque la mthode notifie de la personne pour informer les observateursduchangementdevaleurdunombredepoints.
- 10 -
[Link]
[Link] implantationesttrssimple:
q
import [Link].*; public class DictPersistantProxy<T extends Object> implements DictPersistantIntf<T> { DictPersistant<T> dictPersistant = new DictPersistant<T>(); Map<String,T> contenu = new TreeMap<String,T>(); public boolean ajoute(String cl,T objet) { boolean rsultat = [Link](cl, objet); if (rsultat) [Link](cl, objet); return rsultat; }
- 11 -
public T get(String cl) { T rsultat; rsultat = [Link](cl); if (rsultat == null) { rsultat = [Link](cl); if (rsultat != null) { [Link](cl, rsultat); } } return rsultat; } }
- 12 -