IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

JSF Java Discussion :

Comment bien utiliser JSF?


Sujet :

JSF Java

  1. #1
    Membre expérimenté
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2004
    Messages
    1 184
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Avril 2004
    Messages : 1 184
    Points : 1 745
    Points
    1 745
    Par défaut Comment bien utiliser JSF?
    Bonjour,

    Je voudrai avoir votre avis sur la façon dont j'utilise JSF.

    Mon application est composée comme suit :

    - Presentation : JSF
    - Application : <façade> EJB Session Stateless
    - Métier : Divers EJB

    J'utilise JSF seulement pour effectuer de la présentation. En règle général les composants de es pages sont bindées à des DTO récupéré depuis l'EJB de façade. Ce qui me donne une schéma de ce genre.

    Page JSF <---> managedBean.unDTO <---> <façade> EJB <---> autres EJB


    Après voici les question sur lesquelles je réfléchis, mais je manque encore de pratique JSF :

    1) Quel scope privilégier pour les managed beans?
    Privilégier le scope Request, utiliser le scope session dans les cas ou le scope request ne suffit pas (ex : enchainement sur plusieurs page, équivalent du scope Process d'ADF)

    2) Utiliser quel type de binding ?
    J'utilise le binding par instance de composant (par l'attribut binding des composants) le moins souvent possible (en fait uniquement lorsque je ne peux pas faire autrement) et privilégie donc le binding de valeur. (JDeveloper propose de lier systématiquement chaque composant de l’interface à une propriété d’un bean)

    3) Combien de beans par page ?
    Pour le moment j’utilise un bean par fonctionnalité.
    Ex :
    - 1 page = 1 bean de login pour afficher la personne enregistrée + 1 bean lié à la fonctionnalité
    - n page = 1 bean si elles sont liées (ex : 1 page pour ajouter, 1 page pour voir et une autre pour éditer une lister d’objets)

    4) Que mettre dans les managed beans ?
    Pour le moment, dans la mesure ou le nombre de lignes de code n’est pas trop important, je met tout :
    - binding valeur
    - binding instance de composant
    - methodes d’actions
    - EventListeners
    - Validators
    - …
    Dans le cas ou le bean deviendrai trop important comment séparer les éléments en plusieus beans ?


    Voila j’aimerai avoir votre avis sur l’architecture de mon application, sur les questions posées ci-dessus, ainsi que sur les éléments de réponse que j’ai essayé d’apporter.

    D’autres questions viendront surement plus tard

  2. #2
    Expert éminent
    Avatar de djo.mos
    Profil pro
    Inscrit en
    Octobre 2004
    Messages
    4 666
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2004
    Messages : 4 666
    Points : 7 679
    Points
    7 679
    Par défaut
    Bonjour.
    Tout d'abord, je tiens à te dire que c'est un excellent sujet et fort intéressant : y'a presque pas de doc de qualité sur la structuration des managed beans dans JSF, etc, et j'ai du mettre au point mes propres patterns suite à de nombreux projets, ce qui n'est pas toujours très rassurant !

    Une autre chose, je ne parlerais pas de la couche Model, car c'est très variable et ça dépend vraiment de l'application. Néanmoins, je présume qu'au moins il adhère au pattern DTO/DAO.

    Personnellement, et comme j'utilise JSF actuellement dans une très grosse application, je dois réduire autant que possible le nombre des managed beans, sinon le projet risque de devenir ingérable.
    J'ai décidé de créer un managed bean par fonctionnalité logique et pas atomique. J'explique : en général, dans une application informatique (de gestion) on fait du CRUD (Create, Read, Update, Delete) sur une entité. Je regroupe ces 4 fonctionnalités de base en un seul managed bean, que j'appele EntityController. Ce dernier contient alors :
    • un DTO newEntity que j'utilise pour le binding avec le formulaire de création d'une nouvelle entité.
    • un DTO editEntity que j'utilise pour le binding avec le formulaire d'édition d'une entité.
    • un DataModel entityModel : une liste de DTOs utilisés généralement avec le composant Table pour l'affichage.
    • L'action create : utilise le newEntity pour l'insérer dans la BD et rafraichir l'entityModel
    • L'action update : utilise l'editEntity pour mettre à jour une entité et rafraichir l'entityModel
    • L'action delete : pour supprimer une entité.
    Concernant ta question sur la complexité d'un managed bean, ceux du CRUD sont de bons candidats vu qu'ils réalisent 4 opérations en plus des attributs qu'ils exposent, mais j'ai pu m'en tirer en utilisant l'héritage + généricité : mes Controllers CRUD finaux font rarement plus de 10 lignes !
    réussi
    J'ai aussi à concentrer ces 4 opérations dans une seule page JSF (mais c'est un choix personnel, et beaucoup le trouvent bizarre !) pour éviter l'explosion du nombre des pages.
    Ainsi, je me retrouve dans 90% des cas avec un Controller (managed bean) par page.

    Voilà, j'espère à la fin que ce topic aura le succès et l'audience qu'il mérite.

  3. #3
    Membre expérimenté
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2004
    Messages
    1 184
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Avril 2004
    Messages : 1 184
    Points : 1 745
    Points
    1 745
    Par défaut
    Citation Envoyé par Modjo
    en utilisant l'héritage + généricité : mes Controllers CRUD finaux font rarement plus de 10 lignes !
    Tu as une classe mère générique qui implémente toute les fonctionnalités de crud, puis tu l'étend en spécifiant le type c'est bien ça ?


    Citation Envoyé par Modjo
    J'ai aussi à concentrer ces 4 opérations dans une seule page JSF (mais c'est un choix personnel, et beaucoup le trouvent bizarre !) pour éviter l'explosion du nombre des pages.
    Comment tu le réalises ? Un truc du genre
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    if( editMode )
    {
         afficherEditerEntité
    }else{
    ...
    }
    avec des tags conditionnels ??

    Au niveau des bindings tu a tendance a utiliser plutot les instance de composant, pour les valeurs ?

    Et sinon une autre question me vient à l'esprit?
    • Ou fais tu tes appels pour récupérer les données dans le managed bean :
    • Constructeur ?
    • Méthode getXXX ?
    • méthode init() appelée sur un évènement ?
    • ...

  4. #4
    Expert éminent
    Avatar de djo.mos
    Profil pro
    Inscrit en
    Octobre 2004
    Messages
    4 666
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2004
    Messages : 4 666
    Points : 7 679
    Points
    7 679
    Par défaut
    Bonjour.
    Citation Envoyé par mad-math
    Tu as une classe mère générique qui implémente toute les fonctionnalités de crud, puis tu l'étend en spécifiant le type c'est bien ça ?
    En effet oui ! Ca donne quelque chose du genre :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    public class ArticleController extends CrudController<Article> {
      public ArticleController(){
        super(new ArticleFactory(), new ArticleService());
      }
    }

    J'utilise le Factory Pattern et une couche service.

    Citation Envoyé par mad-math
    Comment tu le réalises ? Un truc du genre
    Code :

    if( editMode )
    {
    afficherEditerEntité
    }else{
    ...
    }

    avec des tags conditionnels ??
    C'est presque ça, je fais plutôt :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    <h:panelGroup rendered="#{articleController.editMode}">
      :
      :
    </h:panelGroup>
    Je passe par l'attribut rendered : c'est plus simle et sûr que d'utiliser <c:if> de JSTL.

    Citation Envoyé par mad-math
    Au niveau des bindings
    Je fais
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    <h:inputText value="#{articleController.editEntity.name}" />
    Je fais le binding avec les attributs des DTOs eux même déclarés comme attribut dans mes Controllers.

    Et j'ai pas bien compris ta dernière question !

  5. #5
    Membre expérimenté
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2004
    Messages
    1 184
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Avril 2004
    Messages : 1 184
    Points : 1 745
    Points
    1 745
    Par défaut
    Pour essayer d'expliquer mieux, j'ai mon EJB session qui possède une méthode

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    Collection<XXXDTO> getListeXXX()
    Mon bean possède une collection de DTO qui est bindée à un datatable

    J'ai donc plusieurs possibilitées pour mon managed bean

    1) Faire l'appel dans le constructeur
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    class ManagedBean {
        Collection<XXXDTO> colDTO;
        ManagedBean(){
            colDTO = ejb.getListe()
        }
        // suivent les getter et setter de colDTO
        ...
    }
    2) Faire l'appel dans le getter
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    class ManagedBean {
        Collection<XXXDTO> colDTO;
     
        Collection<XXXDTO> getColDTO() {
            colDTO = ejb.getListe();
            return colDTO;
        }
        ...
    }
    bref quel est le meilleur endroit pour récupérer les données ? pour l'instant je le met dans le constructeur.

  6. #6
    Membre habitué
    Inscrit en
    Décembre 2002
    Messages
    186
    Détails du profil
    Informations forums :
    Inscription : Décembre 2002
    Messages : 186
    Points : 130
    Points
    130
    Par défaut
    1) Quel scope privilégier pour les managed beans?
    C'est le flou total avec jsf. Il est recommandé d'utiliser le bean associé à une page (ViewControler) en portée request. Par contre tu peux garder certains objets en session et éviter à chaque fois les phases d'initialisation.
    La portée session pour un bean de page est parfois nécessaire avec les valueChangeListener je crois. Mais le gros soucis, c'est de gérer correctement les données en session, c'est un véritable casse tete.

    Je te conseil de regarder du coté de JBoss Seam, qui a partir des scopes request, session & application émule d'autre portée très interessante et les gère à ta place.

    2) Utiliser quel type de binding ?
    par valeur tant que c'est possible!
    dans certains cas tu n'aura pas le choix, mais apres il faut bien maitriser le cycle jsf et l'arbre des composants...

    3) Combien de beans par page ?
    Super idée que celle d'implémenter un controler générique, surtout si ca correspond à tes besoins, en JSF c'est tres facile de faire un form de recherche et un tableau résultat qui sert de visualisaation / édition + création + suppression.
    Par contre je déconseil 1 bean pour n page. Dans le cas où ton tableau éditable ne te suffit pas et que tu as besoin d'une autre page, il vaut mieux creer un 2eme bean

    4) Que mettre dans les managed beans ? Dans le cas ou le bean deviendrai trop important comment séparer les éléments en plusieus beans ?
    tu peux avoir un seul managed bean (au sens jsf) qui contient d'autres bean: par ex. ton managed bean va contenir toutes les action/event, des méthodes utilitaires + un bean pour les données, un bean pour les composants bindés, un bean pour les méthodes de workflow, ...

    tu peux également laisser jsf injecter ces bean (qui deviennent donc des managed-bean) dans un managed-bean, mais comme dit Modjo, ca peux vite devenir illisible (bien qu'on puisse spliter les fichier de config).

  7. #7
    Expert éminent
    Avatar de djo.mos
    Profil pro
    Inscrit en
    Octobre 2004
    Messages
    4 666
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2004
    Messages : 4 666
    Points : 7 679
    Points
    7 679
    Par défaut
    mad-math > Je vois ! mais ça dépend vraiment du contexte ! En tout cas, je le fais jamais dans le constructeur du managed-bean ! J'ai pas de contrôle sur quand est ce que c'est appelé, et ça peut l'être avant que la couche de persistence ne soit prête !

    Citation Envoyé par mauvais_karma
    Citation:
    1) Quel scope privilégier pour les managed beans?
    C'est le flou total avec jsf.
    Pas vraiment flou ! A mon avis, c'est à toi de décider selon tes besoins ! par exemple, dans mon cas, j'utilise fréquemment le Session scope, puisque je fais les 4 opérations (CRUD) dans une seule page, je dois donc garder impérativement l'état de mon managed bean !

    En ce qui concerne le framework Seam, c'est vrai que ça a l'air vraiment interessant, mais j'avoues qu'actuellement je ne trouve pas le temps de le tester ....

    Citation Envoyé par mauvais_karma
    Citation:
    2) Utiliser quel type de binding ?
    par valeur tant que c'est possible!
    dans certains cas tu n'aura pas le choix, mais apres il faut bien maitriser le cycle jsf et l'arbre des composants...
    Tout à fait d'accord ! D'ailleurs dans l'application sur la quelle je travaille actuellement, j'ai jamais eu besoin d'autre binding que par valeur !

    Citation Envoyé par mauvais_karma
    Citation:
    4) Que mettre dans les managed beans ? Dans le cas ou le bean deviendrai trop important comment séparer les éléments en plusieus beans ?

    tu peux avoir un seul managed bean (au sens jsf) qui contient d'autres bean
    Voilà ! J'ai frequemment recours à cette technique : je construis une hiérarchie de controlleurs, pour émuler en quelque sorte la hiérarchie des DTOs ! Mais je laisse jamais JSF y toucher ! En fait, ces ous controlleurs prennent généralement le DTO parent comme paramètre dans le constructeurs, alors c'est moi qui les instancie.

  8. #8
    Membre expérimenté
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2004
    Messages
    1 184
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Avril 2004
    Messages : 1 184
    Points : 1 745
    Points
    1 745
    Par défaut
    Bon la je suis partie pour essayer l'archi suivante côté JSF (je travail actuellement sur une petite application de test)

    un controller MaFonctionnalitéController (managed bean)
    qui contient (composition) :
    - un bean MaFonctionnalitéView qui contient les bindings par instance des composants (peut être inexistante)
    - un bean MaFonctionnalitéModel : qui contient les DTO

    Le controller contient aussi les actions et autres event handler....
    Qu'en pensez vous ?

    Par contre je ne sais pas si il faut déclarer les beans autre que le controller en managed bean ou non? Les dédclarer en propriété du controller dans faces-config ?

    En ce qui concerne le lien entre les deux beans et le controlleur :
    - Composition ?
    - Récupération par le FacesContext : facesContext.getApplication().getVariableResolver().resolveVariable(facesContext, "loginMB")

  9. #9
    Membre habitué
    Inscrit en
    Décembre 2002
    Messages
    186
    Détails du profil
    Informations forums :
    Inscription : Décembre 2002
    Messages : 186
    Points : 130
    Points
    130
    Par défaut
    Ca m'a l'air pas mal!

    Par contre je ne sais pas si il faut déclarer les beans autre que le controller en managed bean ou non? Les dédclarer en propriété du controller dans faces-config ?
    Si ton bean controler est en portée request et qu'un bean qui encapsule des données doit être mis en session, alors tu peux déclarer se dernier dans le facesconfig en scope session, et il sera automatiquement injecté à chaque construction du controller, sans avoir a récupérer le sessionMap ou lex valueBinding.

    Je pense que la composition est suffisante dans les autres cas...

Discussions similaires

  1. Comment bien utiliser ce forum ?
    Par Community Management dans le forum Bibliothèques et frameworks
    Réponses: 0
    Dernier message: 28/01/2007, 17h13
  2. [Optimisation] Comment bien utiliser le StringBuffer?
    Par mathieu dans le forum Langage
    Réponses: 4
    Dernier message: 17/05/2004, 14h22
  3. Comment bien utiliser ce forum ?
    Par Alcatîz dans le forum Pascal
    Réponses: 0
    Dernier message: 21/04/2004, 16h37

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo