Voyage au pays des Patterns

Programming, Design Patterns, Application Design · notes

Browse all génie logiciel documents

3.2. Voyage au pays des Patterns

Pour bien appr hender l'int r t des Patterns, le mieux est de r fl chir

la conception d'une application et de voir petit petit quels besoins ou

probl mes apparaissent. Pour

r pondre chaque besoin, nous

essaierons de piocher un Pattern standard de notre biblioth que: celle

constitu e des 23 Patterns du GOF (GOF signifie Gang Of Four, soit la

bande des quatre auteurs qui ont crit

le livre phare mentionn

pr c demment).

L'application "cas d' cole" que nous avons choisie est un syst me de

gestion d'articles et de news. Nous nous proposons d'en concevoir

la fois le processus de publication et celui de lecture et de navigation

travers les articles. L'objectif n'est absolument pas d' tre exhaustif ou

tr s pr cis concernant les aspects fonctionnels de ce syst me, mais bel

et bien d'introduire progressivement les Design Patterns.

3.2.1. Cahier des charges

Les besoins fonctionnels de notre application sont extr mement

simples: il s'agit pour les auteurs d'articles ou de news d' tre capables

de r diger leurs crits (cette partie n'est pas int grer dans le syst me),

puis de les publier. Si d'aventure plusieurs auteurs tentaient de publier le

m me jour, un m canisme de gestion des priorit s devrait choisir

l' l ment publier et mettre les autres en attente d'une date de

publication ult rieure.

D'autre part, tant pour les auteurs que pour leurs lecteurs, il doit tre

possible de faire des recherches simples parmi tous ces articles et de lire

ceux qui les int ressent.

Afin d' viter les mauvaises surprises, un m canisme de tol rance aux

pannes devra tre mis en Suvre. Il peut s'agir d'une sauvegarde

p riodique, condition que la d perdition de performances ne se fasse

pas sentir lorsque cette sauvegarde s'ex cute.

Enfin, au cas o d'autres outils seraient utilis s l'avenir pour g rer les

articles et news, le syst me doit disposer d'un m canisme d'export dans

Design Patterns

32 / 257

un format neutre (un document XML semble tout indiqu ).

3.2.2. Conception initiale

Afin d' tre brefs sur cette partie, nous allons faire une grosse entorse

au processus habituel de recueil des besoins, d'identification des cas

d'utilisation, de d couverte des objets m tier, d'analyse statique et

dynamique... en esp rant que les experts de ces tapes (tels que Pascal

Roques, cf Bibliographie) ne nous en voudront pas trop.

Supposons donc que nous ayons mod lis les objets m tier la va-vite

et que nous soyons arriv s au r sultat suivant.

Livrable

-date:DateTime

-titre:string

-auteur:string

-sujet:string

-etat:int

+Publier(datePublication:DateTime):void

+Afficher():void

+Imprimer():void

+SoumettreAPublication():void

+ExporterEnXML():void

+Sauvegarder():void

Catalogue

*

+Rechercher(titre:string):Livrable

+Ajouter(nouveau:Livrable):void

+ExporterEnXML():void

+Sauvegarder():void

+Rechercher(auteur:string):Livrable[]

Article

-urlContenu:string

+SoumettreARelecture():void

+ExporterEnXML():void

+Sauvegarder():void

News

+ExporterEnXML():void

+Sauvegarder():void

Figure 6. Conception initiale

Il est certain que ces quatre classes vont r pondre aux besoins

Design Patterns

33 / 257

exprim s dans le cahier des charges. Mais cette conception est-elle

satisfaisante pour autant? Si l'on adopte le point de vue du concepteur

Objet, la r ponse est n gative, et ce pour de nombreuses raisons.

Prenons tout d'abord nos sacro-saints principes de conception:

"

"

"

"

"

Les objets m tier portent des responsabilit s techniques. Par

exemple, le Livrable impl mente les services Afficher(), Imprimer(),

Sauvegarder(), ExporterEnXML(), ce qui ne r pond pas au crit re de

l'Inversion des D pendances.

Un corollaire du point pr c dent est que toutes les m thodes de la

classe Livrable (il en va de m me pour les autres classes, en r alit )

ne visent pas le m me objectif. Certaines sont l pour r pondre des

besoins de sauvegarde, d'autres aux besoins fonctionnels de

l'application... On sent entre elles une faible coh sion.

Ces m mes services techniques peuvent tre amen s voluer. Le

format d'export XML en particulier est susceptible de changer avec le

temps et avec les besoins d'int gration aux applications connexes. Or

si l'impl mentation de ce service est du ressort du Livrable, nous ne

pourrons pas faire voluer le format XML sans toucher au code de

cette classe. En cons quence, le crit re de l'Ouvert-Ferm n'est pas

respect non plus.

Pour reformuler le point pr c dent, il existe un couplage fort entre

le format d'export XML et les classes Livrable, Article et News.

En fait, le seul principe qui soit satisfait dans notre conception est

celui de la substitution de Liskov, car les Articles et les News sont

bien des livrables dans le domaine mod lis , et chaque cas

d'utilisation d'un Livrable garde tout son sens si on l'applique un

Article ou une News.

Ce n'est pas tout. D'autres critiques de conception peuvent tre

formul es du point de vue de la maintenabilit ou de l' volutivit :

"

"

La gestion de l' tat du Livrable n'est pas claire; elle sera certes

explicit e dans le code mais elle restera compl tement opaque du

point de vue de la conception.

Il n'y a aucun d couplage entre les processus m tier,

les

l'affichage ou l'impression des

interactions avec l'utilisateur et

Design Patterns

34 / 257

Livrables. Le cycle de vie de ces diff rentes parties du logiciel est

donc vou tre le m me, alors que ce n'est pas forc ment le cas

dans le domaine m tier mod lis ; il est m me probable que la charte

graphique volue, ou que le processus de s lection de la date de

publication d'un article change, alors que les objets m tier Livrables,

Article et News, ont peu de chances de changer aussi vite.

"

Il semble difficile de garder la trace de l'historique du d roulement

des publications, et donc de faire des statistiques qui permettraient

ventuellement d'am liorer leur processus.

Forts de toutes ces critiques, nous allons essayer d'am liorer la

conception de ce petit syst me en appliquant progressivement les Design

Patterns.

3.2.3. Diff rencier le contexte

Attardons-nous sur la publication d'un nouveau Livrable. Si aucune

publication n'est planifi e, le processus est tr s simple: il suffit de rendre

ce nouveau Livrable disponible dans la liste des publications, tous les

lecteurs pourront en prendre connaissance imm diatement. Si par contre

au moins une publication est d j planifi e, il faut mettre le nouveau

livrable en attente de la disponibilit d'une date.

serions

tent s de g rer

Intuitivement, nous

le contexte dans

l'impl mentation de la m thode Ajouter(nouveau:Livrable) de la

classe Catalogue. Mais tout changement fonctionnel aurait un impact

sur

la

responsabilit d'ajouter un livrable un autre objet que le Catalogue, un

objet qui pourrait tre diff rent selon qu'une publication est ou non en

attente.

Il vaudrait donc mieux d l guer

cette impl mentation.

Advertisement

Design Patterns

35 / 257

Catalogue

+Ajouter(nouveau:Livrable):void

+

etat

EtatCatalogue

+Ajouter(nouveau:Livrable):void

RienAPublier

PublicationPlanifiee

+Ajouter(nouveau:Livrable):void

+Ajouter(nouveau:Livrable):void

Figure 7. tat

On appelle ce Pattern tat car on d l gue la nouvelle classe

EtatCatalogue la responsabilit de g rer le comportement du Catalogue

dans un tat donn . Chaque tat sp cifique est en r alit g r par une

classe fille d'EtatCatalogue (nous n'avons ici que deux tats diff rents:

RienAPublier et PublicationPlanifieee), ce qui fait que chaque classe

n'a qu'un objectif, et qu'un changement fonctionnel tel que l'ajout de

nouveaux cas particuliers pourra se faire en ajoutant de nouvelles

classes filles d'EtatCatalogue.

La m thode Ajouter(nouveau:Livrable) du Catalogue ne fait plus que

d l guer la m thode Ajouter(nouveau:Livrable) de l' tat courant. Et

c'est bien l que tout se joue: selon le type r el de l' tat courant, le

comportement sera diff rent gr ce au polymorphisme.

il

Bien s r, le diagramme de classes ne repr sente que la partie statique

du Pattern;

transitions, qui

correspondent simplement au "changement d' tat", c'est- -dire

l'affectation au Catalogue d'une r f rence vers le nouvel tat. Cette

affectation est souvent effectu e l'initiative des tats eux-m mes, qui

faut galement

impl menter

les

Design Patterns

36 / 257

l'on fait porter la responsabilit de conna tre (ou de choisir) l' tat

suivant.

Outre l' volutivit , ce Pattern permet d'impl menter la perfection les

diagrammes d' tats-transition UML et d'avoir une bijection, donc une

tra abilit parfaite, entre le nombre d' tats dans les diagrammes et le

nombre de classes de conception.

3.2.4. Comment choisir la prochaine

publication?

Finissons-en avec le processus de publication: vous vous tes

certainement dit que le choix de la prochaine publication pouvait se faire

de diverses mani res (la premi re soumise est la premi re publi e, ou

les Articles avant les News, ou une alternance savante entre Articles et

News...). Or celle pour laquelle nous allons opter aujourd'hui pourrait

bien ne pas convenir, auquel cas il faudrait en changer demain.

Il

faut donc trouver une technique l gante pour fixer un choix

aujourd'hui et tre capable d'en changer demain sans qu'il n'y ait

d'impact sur le reste de l'application. La solution ressemble au Pattern

pr c dent et tire elle-aussi profit de la d l gation:

Design Patterns

37 / 257

PublicationPlanifiee

StrategiePlanification

+

strategie

+Ajouter(nouveau:Livrable):void

+Ajouter(nouveau:Livrable):void

FIFO

Pondere

+Ajouter(nouveau:Livrable):void

+Ajouter(nouveau:Livrable):void

ArticlesPrioritaires

+Ajouter(nouveau:Livrable):void

Figure 8. Strat gie

Strat gie et tat

se ressemblent donc norm ment dans

leur

conception. La s mantique, elle, est bien diff rente car si la strat gie est

choisie par param trage de l'application ou par le biais d'une interface

utilisateur, les tats quant eux voluent en autonomie au cours du

fonctionnement de l'application.

3.2.5. Comment exporter les Livrables dans un

format neutre?

Dans notre conception initiale, nous avons choisi d'ajouter la m thode

ExporterEnXML() chaque objet m tier,

leur faisant ainsi porter la

responsabilit de "s'exporter eux-m mes" dans ce format. En effet, qui

mieux que l'objet Article pourrait savoir qu'il faut exporter l'attribut

urlContenu sous forme d'une balise <UrlContenu> par exemple?

Mais critiquons ce choix. D'une part, il donne aux objets m tier une

responsabilit technique et l'inversion des d pendances nous rappelle

recommandable. D'autre part,

qu'une telle conception n'est pas

imaginons que le format du document XML d'export change (son sch ma

Design Patterns

38 / 257

volue): nous risquons alors d'avoir apporter des modifications dans le

code de plusieurs objets m tier, au pire dans tous! C'est inacceptable.

De plus, cette approche ne permet d'avoir qu'un seul format d'export. En

supporter plusieurs requerrait d'ajouter autant de m thodes techniques,

sur tous les objets m tier, que de formats diff rents (binaire, CSV, un

autre sch ma XML...).

Pour toutes ces raisons, nous ne pouvons pas nous contenter de cette

conception "brouillon". Pour rationaliser, il faudrait rassembler dans une

nouvelle classe les sp cificit s du format d'export, tout en conservant la

possibilit de choisir dynamiquement parmi plusieurs formats en fonction

des besoins. Cerise sur le g teau, il faudrait que les objets m tier soient

le moins coupl possible ce m canisme d'exportation, de m me

l'algorithme d'exportation la structure des objets en m moire, en

particulier leur organisation (en liste, en arborescence...). Que

pensez-vous de cette nouvelle conception:

Catalogue

Livrable

+Accueillir(v:IVisiteur):void

*

+Accueillir(v:IVisiteur):void

Article

News

+Accueillir(v:IVisiteur):void

+Accueillir(v:IVisiteur):void

<< interface >>

IVisiteur

+Visiter(a:Article):void

+Visiter(n:News):void

+Visiter(c:Catalogue):void

ExportXMLVisiteur

+Visiter(a:Article):void

+Visiter(n:News):void

+Visiter(c:Catalogue):void

Figure 9. Visiteur

Vous l'aurez compris, la seule chose que l'on demande aux objets

Design Patterns

39 / 257

m tier est "d'accueillir" un Visiteur et de le faire progresser sur

l'ensemble des objets d pendants: par exemple, le Catalogue invoquera

la m thode Visiter(this) sur le Visiteur, puis bouclera sur les livrables

dont il a la charge pour que le Visiteur ait l'occasion de tous les

parcourir.

Nous avons ainsi d coupl les objets m tier de la technique d'export,

ce qui nous permet d'imaginer autant de formats diff rents que cela est

n cessaire. Chaque format donnera lieu une nouvelle impl mentation

du IVisiteur.

3.2.6. Parcourir les livrables soi-m me

Le Visiteur que nous avons mis en Suvre pr c demment n'est pas le

seul devoir parcourir le graphe des objets m tier. Certains algorithmes

auront eux aussi ce besoin, mais tous ne pourront pas devenir des

visiteurs, soit parce qu'ils voudront parcourir le graphe de diverses

mani res (parcourir les news d'abord, les articles ensuite, ou encore un

parcours de livrables tri s ou filtr s selon certains crit res), soit parce

qu'ils souhaiteront piloter le parcours au lieu de se laisser guider par le

graphe d'objet lui-m me.

Dans ce cas, il faudrait que les classes clientes des objets m tier (les

algorithmes qui utilisent ces objets) aient un acc s en lecture toutes

les propri t s mono- ou multi-valu es. Or prenons l'exemple du

Catalogue: s'il donnait ses client la visibilit directe de sa collection de

Livrables, rien n'emp cherait ceux-ci d'ajouter ou de supprimer des

Advertisement

Livrables sans que le Catalogue ne puisse exercer de contr le! Nous

venons de briser l'encapsulation.

l'It rateur.

Pour contourner ce probl me tout en permettant aux clients d'arpenter

librement le mod le objet, il existe deux Design Patterns: le D corateur

et

le

comportement nominal d'un objet, mais nous allons l'utiliser ici dans un

mode d grad : lorsqu'un client souhaitera parcourir la collection des

Livrables,

fournira bel et bien un objet de type

Collection, mais dont seules les op rations de lecture seront autoris es.

le Catalogue lui

normalement

d'enrichir

premier

permet

Le

Design Patterns

40 / 257

Catalogue

+

Livrables

<< interface >>

Collection

contient

Livrable

*

+Ajouter(obj:object):void

+Supprimer(obj:object):void

+Lire(indice:int):object

Delegue

CollectionLectureSeule

+Ajouter(obj:object):void

+Supprimer(obj:object):void

+Lire(indice:int):object

Ajouter et Supprimer

lancent une exception

l'ex cution

Figure 10. D corateur

Cela peut para tre satisfaisant, mais en r alit , nos principes de

conception ne sont pas tous satisfaits. En particulier, notre d corateur

ne r pond pas au principe de substitution de Liskov puisque

l'utilisation d'une CollectionLectureSeule en lieu et place d'une Collection

n'est pas neutre et ne peut pas tre trait e sans pr caution

suppl mentaire: l'utilisateur typique d'une Collection ne sera pas pr t

rattraper les exceptions que l verait une CollectionLectureSeule! En

d corant ainsi la Collection, nous avons donc rompu le contrat qui la

lie ses utilisateurs (celui de r pondre aux services Ajouter() et

Supprimer() sans lever d'exception). D'un autre cot , cette solution est

tr s simple mettre en Suvre et sa consommation en ressources

suppl mentaires est n gligeable; elle ne requiert pas, par exemple, de

dupliquer la Collection que les clients souhaitent parcourir.

Dans le cas o l'on souhaite maximiser la robustesse ou faire varier le

mode de parcours d'un client travers le graphe d'objets m tier, notre

second Pattern est plus adapt : l'It rateur. A l'image de ce que

proposent la plupart des biblioth ques d'acc s aux donn es avec la

notion de Curseur, l'It rateur est un objet d di un seul client la fois

et qui permet de parcourir en lecture seule une collection d'objets. Outre

le fait qu'il simplifie le parcours travers une structure de donn es,

Design Patterns

41 / 257

l'It rateur est galement un excellent outil de d couplage entre la

l'arpente. En effet, quelle que

collection d'objet parcourus et celui qui

soit l'organisation interne des objets, on utilise un It rateur toujours de

la m me mani re.

L'It rateur, quant lui, doit avoir une relation privil gi e avec la

collection dont il facilite la travers e. Or l'organisation des objets peut

varier en fonction des types de collections (listes cha n es, listes bas es

sur des tableaux, arborescences tri es...), donc il est n cessaire de

disposer d'un type d'it rateur par type de collection parcourue.

Enfin, toujours pour masquer l'impl mentation l'utilisateur, il faut faire

porter la Collection d'objets elle-m me la responsabilit de cr er le bon

type d'It rateur (en fonction de sa structure de donn es interne). On dit

que la Collection se comporte comme une Fabrique (ou qu'elle porte

une m thode de fabrication).

Collection

+CreerIterateur():Iterateur

<< interface >>

Iterateur

+Avancer():void

+GetElementCourant():Livrable

+GetParcoursTermine():boolean

CollectionIterateur

+CollectionIterateur(aParcourir:Collection):

+Avancer():void

+GetElementCourant():Livrable

+IsParcoursTermine():boolean

Figure 11. It rateur

A noter que l'It rateur que nous avons mod lis est tr s ancr dans le

mod le des objets m tier et qu'il ne pourrait pas tre r utilis dans

d'autres situations. Cette contrainte a amen les concepteurs des

.NET, par exemple, proposer des It rateurs

frameworks Java et

g n riques qui parcourent et

"Object".

renvoient n'importe quel

L'avantage induit est bien videmment la souplesse, qui se paie par une

Design Patterns

42 / 257

diminution de la robustesse de l'application car on peut se tromper lors

du transtypage des objets parcourus et le compilateur n'est d'aucune

aide puisque pour lui, l'It rateur peut se promener sur n'importe quel

Object. Cette g ne n'existe pas en C++ o les Templates permettent

d'impl menter des It rateurs param tr s par le type d'objets qu'ils

parcourent; et fort heureusement, les langages Java 1.5 et C# 2.0 nous

proposent un quivalent aux Templates, les Generics.

"It rateurs modifiables". Ceux-ci

D'autre part, on trouve galement dans certains frameworks des

It rateurs "am lior s" qui permettent de supprimer l'objet courant lors

d'une travers e de structure de donn es. Appelons ce type d'It rateurs

des

tr s pratiques

compar s aux autres techniques de modification des Collections au gr

d'un parcours. Mais mieux y r fl chir, si nous renvoyons un It rateur

modifiable un utilisateur de nos classes, par exemple un utilisateur

du Catalogue, rien ne l'emp cherait de parcourir les Livrables et d'en

supprimer certains sans que le Catalogue ne puisse effectuer le moindre

contr le. Ce qui revient nouveau briser l'encapsulation: il est

quasiment aussi grave de renvoyer un It rateur modifiable qu'une

r f rence sur la Collection d'objets elle-m me.

s'av rent

3.2.7. Interactions avec le syst me

Avoir mod lis et con u les objets m tier d'un syst me est satisfaisant

car on peut d s lors crire du code qui se lit comme de la bonne prose;

du moins, il parle une personne du domaine que la syntaxe d'un

langage de programmation ne fait pas fuir... Mais si l'on n'y prend garde,

solliciter un mod le objet directement am ne souvent un probl me de

tra abilit . En effet,

(d'une couche de

pr sentation par exemple) pouvait invoquer les m thodes des objets

m tier, non seulement nous aurions de nombreuses d pendances mais il

deviendrait surtout tr s difficile de dire quel besoin m tier correspond

chaque invocation ou quelle motivation de l'utilisateur final cette

invocation se rattache.

si n'importe quel objet

Afin de rationaliser l'interaction entre la couche de pr sentation et la

les architectures "multi-couches" nous

couche d'objets m tier ,

recommandent d'ins rer un interm diaire, souvent appel couche de

Design Patterns

43 / 257

services, qui expose un ensemble de Fa ades fonctionnelles. Comme

dans la vie courante, une Fa ade offre un point d'acc s simplifi un

ensemble de services et permet par l -m me de limiter le couplage entre

deux couches logiques successives. Une autre mani re de le dire: la

fa ade masque les d tails dont les utilisateurs ne doivent pas tre

d pendants.

Dans notre exemple,

les utilisateurs finaux souhaitent g rer

les

publications ainsi que les th mes qui les regroupent. Une seule Fa ade

Advertisement

de GestionDesPublications devrait suffire rassembler les principaux

services du syst me; elle devient d s lors un point d'entr e obligatoire

pour les utilisateurs (un contr leur, souvent proche des cas d'utilisation

d termin s en analyse).

GestionDesPublications

+AjouterTheme(theme:string):void

+PublierArticle(theme:string,titre:string,auteur:string,text:string,urlContenu:string):void

+PublierNews(theme:string,titre:string,auteur:string,text:string):void

Figure 12. Fa ade

Comme nous pouvons le constater, la Fa ade est tr s simple utiliser

puisqu'elle se charge de tout:

"

"

La cr ation des objets n cessaires. La Fa ade peut s'appuyer sur

la

une

abstraite)

responsabilit d'instancier les objets concrets.

( ventuellement

d l guer

Fabrique

pour

L'initialisation compl mentaire de ces objets. Certains objets

n'offrent qu'un constructeur sommaire (ou leur fabrique n'offre

qu'une m thode acceptant peu de param tres); il s'agit donc

d'affecter les propri t s qui n'ont pas pu l' tre par le biais de ce

constructeur.

"

L'invocation de m thodes, dans un ordre compatible avec les

workflows applicatifs et m tier.

La Fa ade GestionDesPublications est une classe sans attribut. Ses

il serait

instances sont donc sans tat,

indistincts. Dans ce cas,

Design Patterns

44 / 257

dommage d'en cr er plusieurs puisque chacune de ces instances est

parfaitement identique sa petite sSur.

Pour viter ce g chis, il convient d'interdire la cr ation tout va

d'instances de GestionDesPublications. Comment? En rendant son

constructeur inaccessible aux clients ext rieurs (rendons-le priv par

exemple). Mais de ce fait, il devient n cessaire d'offrir un autre point

d'entr e la GestionDesPublications, qui ne n cessite pas de l'instancier

au pr alable: seule une m thode statique peut faire l'affaire. Et donc

la

sans

GestionDesPublications (la premi re fois qu'on l'invoque), soit de

r cup rer une r f rence cette instance devenue unique (les fois

suivantes).

cette m thode va permettre soit d'instancier

surprise,

Cette gymnastique de l'esprit, qui part du besoin de partager des

informations ou d'optimiser l'occupation m moire par l'interdiction de

cr er plusieurs instances, et qui aboutit une classe l'instance unique

accessible par le biais d'une m thode statique porte un nom: le Design

Pattern Singleton. Dans la phrase pr c dente, on comprend comment

les Patterns permettent d' lever le niveau du langage et de limiter les

ambigu t s entre interlocuteurs avertis.

-instance:GestionDesPublications

GestionDesPublications

<< create >>-GestionDesPublications():

+GetInstance():GestionDesPublications

+AjouterTheme(theme:string):void

+PublierArticle(theme:string,titre:string,auteur:string,text:string,urlContenu:string):void

+PublierNews(theme:string,titre:string,auteur:string,text:string):void

Figure 13. Singleton

3.2.8. Am lioration de la tra abilit

Introduire une Fa ade a certes simplifi l'acc s aux fonctionnalit s

essentielles de notre syst me, mais cela n'a pas am lior la tra abilit ni

la gestion de l'historique des interactions entre l'utilisateur final et le

Design Patterns

45 / 257

syst me. Mais nous sommes pr s du but: puisque nous ne pouvons

il

cataloguer que des objets, et non des invocations de m thodes,

faudrait

classe

chaque

GestionDesPublications soit r ifi e en objet, c'est- -dire qu'il nous

faudrait instancier un objet pour rendre compte de chaque invocation

des m thodes AjouterTh me(), PublierArticle() et PublierNews().

simplement

sollicitation

que

de

la

Afin de banaliser la gestion de toutes ces interactions, nous allons nous

efforcer de respecter le m me contrat dans chacune de ces nouvelles

classes de conception. Typiquement, elles offriront toutes une m thode

Execute() qui permettra de d clencher l'invocation du service associ .

Seules varieront

les

informations sp cifiques n cessaires l'ex cution de chaque commande

(les "Setters"), ainsi que les m thodes de r cup ration des r sultats

ventuels (les "Getters"). Cette mani re de faire s'appelle le Pattern

Commande:

les m thodes qui permettront de fournir

<< interface >>

Commande

+Execute():void

PublierArticleCmd

PublierNewsCmd

AjouterThemeCmd

-auteur:string

-sujet:string

-titre:string

-urlContenu:string

+Execute():void

-sujet:string

-auteur:string

-titre:string

+Execute():void

-sujet:string

+Execute():void

Figure 14. Commande

La Commande pr sente l'avantage de simplifier la tra abilit entre les

besoins des utilisateurs finaux et leur impl mentation dans le syst me.

Mais tout de m me, quelle lourdeur pour arriver quelque chose qui ne

semble pas tr s loign de la simple Fa ade pr c dente!

Design Patterns

46 / 257

Non, en r alit , la valeur ajout e de la Commande sur la Fa ade est

ailleurs. Chaque invocation de service est maintenant un objet en

m moire, et il en d coule de nombreuses (bonnes) propri t s:

"

"

"

"

"

Il est maintenant possible de cr er un historique de tous les

services sollicit s par les utilisateurs finaux.

En cas de probl me majeur, il sera donc toujours possible de

rejouer les derni res commandes d'un utilisateur pour remettre

le syst me dans un tat coh rent.

Certains domaines peuvent

tirer parti de la connaissance des

op rations d clench es par un client. La gestion de la relation client

en particulier est friande de ce type de renseignement. De m me

pour la gestion de la navigation des utilisateurs travers un site

Web.

nous

Comme

disposons

de

commandes, il devient possible de d faire ce que les commandes

ont fait, dans le sens inverse, puis ventuellement de rejouer les

commandes annul es.

chronologique

historique

d'un

soit

par un interm diaire

Les commandes seront ex cut es soit par celui qui en fait la

Advertisement

demande,

appellerons

l'ordonnanceur de commandes. Ce dernier peut tout fait g rer

une notion de priorit entre commandes, traiter certaines de mani re

asynchrone ou m me d l guer l'ex cution de certaines commandes

d'autres nSuds de traitement du syst me (d'autres serveurs, dans le

cas d'un cluster par exemple).

que nous

Remarque: ce Pattern a t pouss l'extr me dans l'approche par

Pr valence. Suivant les pr ceptes de Bertrand Meyer, les outils comme

Prevayler et Bamboo.NET vont jusqu' distinguer les commandes qui ont

un effet sur l' tat du syst me et celles qui ne font que le consulter.

Seules les premi res sont enregistr es dans un journal de commandes

(typiquement sur disque dur, par s rialisation), ce qui permet, associ

un m canisme de persistance p riodique des objets m tier, d'obtenir un

syst me compl tement fiable, persistant, orient objet... sans utiliser la

moindre base de donn es. Une initiative tr s

int ressante et

prometteuse...

Design Patterns

47 / 257

3.2.9. G rer les v nements applicatifs

Imaginons que les administrateurs du syst me de publication

leur

souhaitent avoir sous les yeux un tableau de bord graphique qui

permette de prendre connaissance en temps r el de l' tat des demandes

de publications de nouveaux Articles.

La premi re technique que l'on peut mettre en Suvre est simple: il

suffit de scruter le Catalogue de Livrables et de r agir en d clenchant

une alarme d s que l' tat d'un Livrable change. Mais pour cela, il faudrait

avoir fait une copie de l' tat de chaque objet et comparer cet tat

"pr c dent" avec l' tat "courant" de chaque objet lors de la scrutation

p riodique. C'est envisageable si le nombre d'objets scruter n'est pas

tr s important ou si la fr quence de scrutation est faible.

Dans le cas contraire, il serait plus judicieux d'inverser la d pendance.

Apr s tout, celui qui para t le plus m me de savoir quand change l' tat

d'un Livrable, c'est bien le Livrable lui-m me. Il suffit donc de faire en

sorte que ce dernier puisse informer, notifier les objets int ress s qu'il

est en train de changer d' tat. Pour cela, le Livrable doit offrir aux objets

ext rieurs un moyen de s'abonner aupr s de lui et de se d sabonner

ult rieurement. Inversement, chaque objet ext rieur doit convenir avec

le Livrable de la m thode d clencher pour notifier son changement

d' tat. Ce m canisme d'Abonnement-Publication, que l'on aper oit

galement dans les Middleware Orient s Message, porte le nom de

"Pattern Observateur-Observable".

<< interface >>

ObservateurDeLivrable

*

+Notification(l:Livrable):void

Livrable

+Abonnement(obs:ObservateurDeLivrable):void

+Desabonnement(obs:ObservateurDeLivrable):void

InterfaceGraphiqueAdministrateur

+Notification(l:Livrable):void

Figure 15. Observateur - Observable

Design Patterns

48 / 257

La m me remarque d j formul e au sujet de l'It rateur s'applique

nouveau ici: notre Observateur est ancr dans le mod le m tier du

syst me de publication puisqu'il ne peut tre notifi que des

modifications de l' tat d'un Livrable. La g n ricit permet de g n raliser

ce Pattern tout en conservant un typage fort.

D'autre part, en particulier si l'on transpose l'Observateur-Observable

dans une architecture distribu e, une question revient souvent: vaut-il

mieux passer syst matiquement l'objet dont l' tat change en param tre

ou se limiter sa r f rence, son identifiant? M me s'il est difficile de

trancher dans le cas g n ral, la premi re solution est souvent choisie:

"

"

Elle n'implique que n invocations de m thodes distance (autant

que d'observateurs), alors que la seconde technique en implique

jusqu' 2*n voire m me davantage (tous les Observateurs risquent

d'invoquer une m thode sur l'Observable pour prendre connaissance

de la modification qui a eu lieu, et ventuellement pour r cup rer le

nouvel tat de l'objet).

Elle garantit

la coh rence des notifications. Dans la seconde

approche,

les Observateurs reviennent vers l'Observable pour

r cup rer les informations compl mentaires; or ce dernier risque

d'avoir encore chang d' tat entre temps! Un tat interm diaire peut

ainsi ne jamais tre port la connaissance de certains

Observateurs.

3.2.10.Am liorer les performances du syst me

syst me

La plupart des Design Patterns que nous avons abord s apportent

notre

de

maintenabilit . Mais rares sont ceux qui visent une am lioration des

performances. Terminons notre voyage dans le monde des Patterns avec

quelques consid rations sur ce th me.

d' volutivit

souplesse,

parfois

plus

de

et

Dans un langage Objets, deux l ments techniques sont

tr s

consommateurs de temps: il s'agit de la construction et de la destruction

des objets. Si nous pouvions trouver une technique pour les limiter au

strict minimum, nous gagnerions certainement un temps consid rable.

Remarque: le Singleton allait d j dans ce sens, mais il ne s'applique

Design Patterns

49 / 257

pas au cas g n ral des classes instanci es de nombreuses fois.

Prenons l'exemple des Articles et des News dans notre application. De

nombreuses instances de chacune de ces deux classes seront cr es au

cours de l'ex cution de l'application, mais si nous utilisons un m canisme

de sauvegarde, il ne sera pas n cessaire de conserver constamment tous

ces objets en m moire. Donc certains objets, une fois sauvegard s, ne

nous seront plus utiles et nous pourrons ainsi les lib rer.

Au lieu de cr er et de "jeter" nos objets apr s usage, ce qui donnera en

Java et en .NET un gros travail au Ramasse-Miettes, nous ferions mieux

de les recycler. Cette solution, plus cologique, est galement plus

efficace puisqu'il ne sera plus n cessaire d'allouer et de d sallouer autant

d'espaces m moire qu'auparavant, ni de d fragmenter la m moire aussi

souvent. Mais qui doit d cider de cr er, recycler ou d truire les objets?

Sur quels crit res?

Pour tre certain de g rer ce probl me de mani re coh rente, il faut

affecter la responsabilit de g rer tout le cycle de vie des Articles

la m me classe, que nous appellerons FabriqueArticles. A travers notre

application, d s que l'on aura besoin de cr er un nouvel Article, il faudra

s'adresser elle. De m me, apr s en avoir termin avec un Article, il

faudra veiller "le lui rendre", de telle sorte que le recyclage puisse avoir

lieu.

FabriqueArticles

+creerArticle():void

+detruireArticle(a:Article):void

*

+

articlesDisponibles

Article

+Recycler():void

Figure 16. Fabrique et Pool d'objets

Design Patterns

50 / 257

De son c t ,

la fabrique g re une collection d'Articles disponibles

(c'est- -dire existant en m moire mais qui ne sont plus utilis s par

personne). Lorsqu'une classe cliente lui demande de cr er un nouvel

Article:

"

"

Si elle dispose d'Articles disponibles, elle en prend un, le recycle et

le renvoie l'appelant.

Dans le cas contraire, elle peut prendre la d cision d'instancier un

nouvel Article, mais comme il est probable qu'on lui demande d'en

cr er encore un nouveau tr s peu de temps apr s, elle peut tr s bien

prendre l'initiative d'instancier plusieurs Articles d'u...