Façade ou pas façade...

[MGZ]Slug

Membre expert
Club iGen
Hey !

J'ai une petite question pour les gens au fait des différents Design Pattern utilisés en programmation-objet. J'ai à faire un premier jet de design pour une application web du genre web store. Le principe de ce petit design est comme vous vous en doutez de mettre en évidence les différents patterns utilisés et d'expliquer l'intérêt de ces patterns. J'avance pas mal, mais j'ai un petit doute quant au pattern d'un des éléments de mon système. Ça ressemble à une façade, sent la façade, mais sur certains détails ça ne colle pas du tout avec une façade. Je n'arrive pas vraiment à trouver à quel pattern ça correspond, et je suis pourtant sûr qu'il y a un pattern bien connu derrière tout ça. Ou peut-être que je me goure complètement (c'est la première fois que je travaille avec les Patterns)

Bon, petite description de mon système. Tout d'abord, les users. Un user de base (non logue) est décoré avec ce qu'il faut quand il se logue (pour garder le caddy, etc... sans avoir a reconstruire un nouvel user et copier tout dans le nouveau). Chaque user possède une instance du ShopManager. Celui-ci contient un objet ShoppingCart, une référence vers l'objet courant + un observateur pour garder les stats. Le ShopManager contient tout un lot de méthodes qui renvoient aux méthodes du ShoppingCart (qui possède un observateur qui va se charger de modifier les infos du stock), du DataBaseProxy, des objets de classe Stock (toutes les infos sur l'état du stock de l'item correspondant, plus les méthodes pour ajouter/enlever/commander/...), et des objets d'interface Item. Saupoudrez-le tous de quelques Singletons et autres Factories, et vous obtenez un bon bordel sans un bon graphe pour tout expliquer. C'est bien dommage, car je n'ai rien pour faire un graphe UML sous la main...

Bref, la question... est-ce que le ShopManager est une façade ? Il conserve une instance de l'item courant et du ShoppingCart... donc il ajoute quelques fonctionnalités. J'ai pensé à peut-être sortir ces deux éléments du ShopManager, et les passer dans l'utilisateur. Mais ça me semblait plus logique de les intégrer dans le ShopManager. Enfin, peut-être que je me trompe (je répète que les Design Patterns c'est vraiment tout nouveau pour moi).

Si jamais quelqu'un a une petite idée ... je suis preneur :D

@++

Guillaume
 
Hum... tu travailles tard (vu l'heure du post)... on va essayer d'apporter un peu d'eau à ton moulin.

Tout d'abord, avant de commencer, tu peux jeter un coup d'oeuil sur Poseidon ou MagicDraw comme modeleur UML.

Pour ce qui est du pattern de Facade, un début d'explication peut se trouver ICI. Comme décrit, le pattern Facade est plutôt dédié pour cacher d'autres services (plusieurs, sinon, on parle d'Adapteur) et de casser les dépendances entre le client est les services.

Prenons un exemple: un user A se logue et veut ajouter un item à son panier, il fait appel pour cela à deux services:
  1. l'authentification
  2. le gestionnaire de panier
Mais tu crées une dépendance entre ces deux services (qui rend tous les services) et le client (coté serveur web). Ajoute à cela que les deux services en question peuvent proposer d'avantages de méthodes, inutiles dans ton cas d'utilisation.
Donc, la solution est d'utiliser le pattern de facade qui va:
  • casser la dépendance entre le code client et chacun des services
  • simplifier la lecture du code (d'un point de vue client), car il n'offre qu'une vision restreinte au strict minimum


Par contre, une chose m'intrigue quant à tes user qui possèdent chacun une instance du shopmanager... j'aurais d'avantage vu le shop manager comme un service sans état et où chaque user possèderait un état qui lui permettrait d'utiliser le shop manager... mais bon, c'est mon coté SOA qui veut ça :D.
 
Dans la mesure où ton ShopManager est threadsafe et sans synchronize, l'option Singleton est à envisager... d'autant que cela ne signifiera pas forcément que tu n'auras qu'une seule instance en mémoire (cas des clusters par exemple)... mais cela supportera la concurence (c'est bien à ça que ça sert un conteneur J2EE ;)).

Tu t'es arrêté à minuit ! Tu avais posé une demi-journée ? :D
 
J'ai fait un rapide graphe UML de tout mon bazar avec Poseidon (j'ai pas inclus le bidule pour la base de donnee et les factories sinon c'est completement illisible...). Si par tu as 5 min pour jeter un oeil histoire juste de me dire si je fais completement fausse route ou pas ...

Enfin, en tout cas je suis bien content d'avoir pris ce court ! C'est vraiment interessant comme sujet. Je suis vraiment degoute de voir que l'on ne voit pas ca dans les Universites France, ou du moins pas aussi bien (juste un survol tout pas interessant !!!).

@+

Guillaume
 

Fichiers joints

  • overview.zuml.zip
    38,1 KB · Affichages: 29
C bon, j'ai trouvé 5 minutes :rateau: !!!

Voici en vrac quelques remarques (personnelles).
  • Bien distinguer les notions d'association: simple, d'aggrégation et de composition ou 'relation'.
  • Passer en asynchrone pour tes statistiques (plutôt que du listener)
  • ne pas utiliser d'abstraction quand elles ne sont pas utilisées
------------

Pour le premier point, le distinguo est important car il te donne des indications sur le cycle de vie des objets:
  • une association simple indique que les deux objets en relations vivent leur vie indépendemment l'un de l'autre.
  • une aggrégation indique une liaison plus forte entre les deux objets
  • une composition indiquera que l'objet composé n'a de sens que tout seul, et donc il n'a pas de raison d'être sans son père (rel. père-fils)
Certes, il peut s'avérer difficile de faire le choix, mais c'est déterminant... surtout après quand tu passes au schéma relationnel pour la persistence.

[mode pas clair]
Autre chose, lorsque tu modélises un service comme ShopManager, certes ses méthodes de services ont des relations avec des entités comme ShoppingCard... mais ce n'est pas pour autant qu'il faut faire apparaître une association. Il s'agit d'avantage d'une relation. En gros, en faisant une association, tu t'attends à voir un attribut du type ShoppingCard dans ShopManager... alors que c'est peut-être un paramètre d'une méthode de ses services ?
[/mode pas clair]


Pour ton module de stat., tu conserves bien sûr le principe du pattern observer/observé, mais en asynchrone. D'où il faut relier les deux objets entre eux, mais pas sous la forme d'une association. En J2EE, on réalise souvent cela à l'aide de messages JMS et de MDB (Message Driven Bean).


L'interface Subject n'a pas de raison (sur ce diagramme du moins) d'exister. A moins qu'il y en ait une fonctionnellement parlant, il n'est pas nécessaire de la représenter, car personne ne l'utilise. De plus, il faut faire attention à ne pas tomber dans le travers de dire: "Objet A a une méthode Toto, objet B a aussi une méthode Toto, donc, ils doivent tous les deux réaliser une interface Truc qui a une méthode Toto" :).


C'est en vrac comme je te disais... et puis en 5 minutes (je dois filer aller boire un café avant de tomber sur le clavier)...

gg
 
Avant toute chose, merci pour ton aide ! Je suis aussi peu habitue a utiliser UML que les Pattern (mais contrairement au Patterns, je n'ai jamais eu de cours la dessus, ni de temps pour regarder par moi-meme).

Je vais essayer d'ameliorer tout ca en utilisant tes conseils. Toutefois, je n'ai pas de plateforme/environnement cible. Donc hormis pour donner des exemples je ne peux pas vraiment parler de Beans, ou autres. Il faut que je reste tres "general".

Enfin, si jamais il y a des dev' amateurs dans le coin qui ont jamais regarde les Patterns, je les encourage a le faire. Vraiment interessant !!!!
 
[MGZ]Slug a dit:
Enfin, si jamais il y a des dev' amateurs dans le coin qui ont jamais regarde les Patterns, je les encourage a le faire. Vraiment interessant !!!!

C'est dans mes projets... pour... quand j'aurais le temps! J'ai déjà un peu d'expérience (Factory, Façade, Builder, Adapter, Singleton) mais je connais pas toujours tous les détails.
Autrement il y a aussi un truc que je veux voir c'est RUP.
 
Très souvent, on s'aperçoit qu'on manipule ou qu'on code des patterns sans même le savoir... question de bon sens.

Là où j'y trouve un interet, c'est pour communiquer: on peut mettre des mots sur des concepts.

Ca permet aussi de tester des candidats en entretien :rateau:.
 
C'est vrai que c'est vraiment pratique pour communiquer. J'ai du faire une presentation de 15min sur un design... et j'etais bien content de pouvoir simplement coller une etiquette sur des elements complexes connus de tous. Ca m'a evite de faire une presentation de 2h :D

Sinon dans un cas de design reel, est-ce que tu te dis : je vais utiliser ce pattern la pour ca, ca ou ca. Ou est-ce que tu pars de ton idee et ensuite tu regardes les patterns qui correspondent a ton idee, ou ceux qui pourraient l'ameliorer ? On nous a conseille la seconde options, mais certains on fait le contraire pour la presentation (les seuls a avoir case sans doute 15 ou 20 differents patterns dans leur designs :D). Generalement ils ont finis avec un truc ultra complique et qui semblait difficilement codable.
 
Les patterns ne sont pas une fin en soi ! Ils sont simplement une réponse adaptée et éprouvée face à des problématiques d'architecture récurents : "Comment limiter la dépendance entre tel et tel composants" ou encore "Comment rendre ce truc moins compliqué à utiliser" etc...

L'option de caser tout et n'importe quel pattern à n'importe quel prix est à banir, car au final la qualité d'un code ne s'apprécie pas uniquement par rapport à l'architecture et aux algos. C'est aussi savoir faire preuve de pragmatisme ! Souvent, la contrainte temps et ressource (compétence) sont là pour calmer les ardeurs :D.

Si tu comprends l'utilité d'une facade ou d'un singleton sans même connaître leur nom, et que tu sais dans quel cas appliquer ces deux patterns, cela vaut bien mieux que d'en connaître une trentaine à tort et à travers... Ceci dit, cette logique s'applique difficilement dans un cadre scolaire.
 
Bah actuellement j'ai eu les resultats des presentations ce matin, on notre approche un poil plus pragmatique nous a valu la meilleure note :D On etait parti du principe : reflechissons d'abord comment on aurait cree ca sans connaitre les patterns, et ensuite voyons ce qui correspond !
 
  • J’aime
Réactions: GrandGibus
comme dit GrandGibus, les patterns ne sont pas une fin en soit !
A ce titre, l'introduction du livre est passionante car elle explique leur sens profond, à savoir : qu'est ce qui fait un bon Design OO, comment avoir un code faiblement couplé, évolutif robuste...

En particulier la destruction de l'idée fausse que l'héritage de classe est la panacée et qu'il faut priviligé, comme c'est illustré dans de nombreux Patterns, l'implémentation d'interface.:up:
 
  • J’aime
Réactions: molgow
C'est quand même un peu provoc'. Je suis tout à fait convaincu qu'il faut éviter au maximum l'héritage lorsque ce n'est pas nécessaire et que d'utiliser des interfaces est vraiment une bonne chose. Pour ce dernier point, essayez une fois de faire un plug-in pour Eclipse et vous verrez qu'il existe des Interface pour tout !!! Par contre ils ont aussi parfois des hiérarchies de classes très lourdes... j'ai eu utilisé des classes qui avaient 7 niveaux de hiérarchie en dessus d'elles! Ça devient vraiment impossible à utiliser... :nailbiting:
Bref, bannir l'héritage c'est un peu casser un des principaux fondement de l'OO non ?


[Edit] Au fait, en ce moment, je fais de l'assistanat en Java pour des débutants en programmation et je me vois mal leur expliquer que l'héritage c'est de la merde et qu'ils doivent pas écouter la prof... :D
 
Et puis l'orienté-objet, c'est dépassé! :D Bientôt on fera tous du l'aspect-oriented, de l'agent-oriented ou du service-oriented :p
(surtout du service-oriented à mon avis ;))
 
Attention, mon propos n'était pas de banir l'héritage sous toutes ses formes.... mais uniquement l'héritage structurel (entre objets concrets)... sinon, je suis à 200 % pour l'héritage fonctionnel (d'interfaces).

Sinon, on peut aussi faire de l'héritage d'aspects... c'est rigolo, encore plus lorsqu'il s'agit de faire de l'inversion de controle (tiens, un pattern) entre services :D.
 
GrandGibus a dit:
Attention, mon propos n'était pas de banir l'héritage sous toutes ses formes.... mais uniquement l'héritage structurel (entre objets concrets)... sinon, je suis à 200 % pour l'héritage fonctionnel (d'interfaces).

Mais tu autorises tout de même l'héritage entre une classe abstraite et une classe concréte ?
Sinon bonjour les copier-coller de morceaux de code... et c'est moche !