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

Langage Java Discussion :

Méthode de fabrique Static


Sujet :

Langage Java

  1. #1
    Membre régulier
    Profil pro
    Inscrit en
    Septembre 2006
    Messages
    287
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2006
    Messages : 287
    Points : 100
    Points
    100
    Par défaut Méthode de fabrique Static
    Bonjour,

    J'ai acheté le livre "JAVA EFFICACE: Guide de programmation" dans lequel il est expliqué qu'il vaut mieux privilégier des méthodes de fabrique statique aux constructeurs.
    Je pense avoir compris le résonnement mais je souhaiterais être sûr de ne pas faire d'erreur, je sollicite donc l'aide de connaisseurs

    Prenons par exemple le cas d'une classe héritant de JButton dont le constructeur serait celui-ci:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    public BoutonPerso(String text, Boolean opaque){
        super(text);
        this.setOpaque(opaque);
    }
    Est ce correct de remplacer ce constructeur par:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    public static BoutonPerso createButton(String aNameString, Boolean opaque){
        BoutonPerso bouton = new BoutonPerso();
        bouton.setText(aNameString);
        bouton.setOpaque(opaque);
        return bouton;
    }
    en ayant au préalablement créer un constructeur privé:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    private BoutonBordsArrondis() {
        super();
    }
    Ou est-ce que je fais totalement fausse route?

  2. #2
    Modérateur

    Avatar de Robin56
    Homme Profil pro
    Architecte de système d'information
    Inscrit en
    Juin 2009
    Messages
    5 297
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Architecte de système d'information

    Informations forums :
    Inscription : Juin 2009
    Messages : 5 297
    Points : 13 670
    Points
    13 670
    Par défaut
    Moi ce qui me bloque dans tout ça c'est ça :
    Citation Envoyé par Micke7 Voir le message
    [...] il est expliqué qu'il vaut mieux privilégier des méthodes de fabrique statique aux constructeurs.
    Ils en donnent la raison dans le livre ? Car moi je ne vois pas pourquoi il faudrait "bannir" l'usage des constructeurs.

  3. #3
    Rédacteur/Modérateur
    Avatar de Logan Mauzaize
    Homme Profil pro
    Architecte technique
    Inscrit en
    Août 2005
    Messages
    2 894
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Architecte technique
    Secteur : Transports

    Informations forums :
    Inscription : Août 2005
    Messages : 2 894
    Points : 7 084
    Points
    7 084
    Par défaut
    1. Pour empêcher la création d'un objet tu n'as que le mécanisme d'exception
    2. La construction d'un objet pouvant être couteuse (l'allocation en soit ainsi que l'initialisation des classes parentes, éventuellement le traitement des imports si la méthode static n'est pas dans la même classe) autant faire d'abord les vérifications nécessaires et ensuite instancier l'objet

  4. #4
    Membre actif Avatar de Mamypirate
    Homme Profil pro
    Samouraï
    Inscrit en
    Mai 2011
    Messages
    108
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Sarthe (Pays de la Loire)

    Informations professionnelles :
    Activité : Samouraï
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Mai 2011
    Messages : 108
    Points : 211
    Points
    211
    Par défaut
    Cela ressemble au pattern Factory si mes souvenirs sont bons.
    Par contre si on prend en compte les remarques de Nemek, l'exemple proposé par Micke7 n'apporte rien de plus que de passer directement par le constructeur.

    Cette façon de faire trouve son utilité dans le cas ou les objets instanciés sont amenés à évoluer ... comme avec des API de binding ou mapping.

  5. #5
    Expert éminent sénior
    Avatar de tchize_
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2007
    Messages
    25 482
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : Belgique

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2007
    Messages : 25 482
    Points : 48 804
    Points
    48 804
    Par défaut
    Dans certains cas, il vaut mieux privilégier des méthodes de fabrique statique aux constructeurs.

    Il s'agit des cas où vous ne voulez pas que l'appelant aie à décider de quel type d'instance il a besoin. Exemple:

    J'ai une classe Rectangle, une class RectangleArrondi en héritant et une classe Carré héritant de Rectangle (avec des calcul optimisé en géométrie vu les caractéristiques spéciales d'un carré, par exemple). Je pourrais envisager cette fabrique

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    public static Rectangle createRectangle(double largeur, double hauteur, double arrondi){
       if (arrondi==0.0)
         return createRectangle(largeur,hauteur);
       else
         return new RectangleArrondi(largeur, hauteur, arrondi);
    }
    public static Rectangle createRectangle(double largeur, double hauteur){
       if (largeur==hauteur)
         return new Carre(largeur);
       return new Rectangle(largeur,hauteur);
    }
    En général, une fabrique sert à instancier une implémentation indéterminée d'une interface. Exemple: toutes les méthodes createBorder de swing, les méthode pour créer des parseur SAX, etc. Ca permet en quelque sort du plug and play entre les librairies. Mais ça doit être limité à ces cas. Pour le reste de votre code: instanciation et constructeur.

    @Nemek:
    Oui, on ne peux que lancer une exception pour arrêter un Constructeur -> C'est logique et c'est de toutes façons la voie à suivre pour les cas d'erreur.
    Gagner du temps en faisant la vérification avant? Aucun sens. On ne gagnerais efficacement du temps que si dans la majorité des cas on ne peux pas instancier. Faire un code qui relève de l'impossibilité d'instancier un objet dans la majorité des cas implique qu'il faut revoir ce code, il y a quelque chose de pas net dedans. De plus, en cas d'impossibilité de créer l'objet voulu, les bonne pratiques veulent qu'on lance une Exception en java -> Une exception prend aussi du temps à être créée, beaucoup de temps


    Il y a aussi un autre cas d'utilisation, celui où les instance retournée peuvent être plusieurs fois les même via l'utilisation d'un cache. Typiquement, mais pas exclusivement, on mettra en place ce genre de chose avec des immutable. Exemple, la méthode Byte.valueOf(byte).

  6. #6
    Rédacteur/Modérateur
    Avatar de Logan Mauzaize
    Homme Profil pro
    Architecte technique
    Inscrit en
    Août 2005
    Messages
    2 894
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Architecte technique
    Secteur : Transports

    Informations forums :
    Inscription : Août 2005
    Messages : 2 894
    Points : 7 084
    Points
    7 084
    Par défaut
    Citation Envoyé par tchize_ Voir le message
    Bouh le code pas beau

    Citation Envoyé par tchize_ Voir le message
    En général, une fabrique sert à instancier une implémentation indéterminée d'une interface. Exemple: toutes les méthodes createBorder de swing, les méthode pour créer des parseur SAX, etc. Ca permet en quelque sort du plug and play entre les librairies. Mais ça doit être limité à ces cas. Pour le reste de votre code: instanciation et constructeur.
    C'est ni plus ni moins que les pattern de frabrique.
    Rien à voir avec une règle d'or

    Citation Envoyé par tchize_ Voir le message
    Oui, on ne peux que lancer une exception pour arrêter un Constructeur -> C'est logique et c'est de toutes façons la voie à suivre pour les cas d'erreur.
    Les exceptions ne sont pas les seuls mécanismes de gestion des erreurs.

    Citation Envoyé par tchize_ Voir le message
    Gagner du temps en faisant la vérification avant? Aucun sens. On ne gagnerais efficacement du temps que si dans la majorité des cas on ne peux pas instancier. Faire un code qui relève de l'impossibilité d'instancier un objet dans la majorité des cas implique qu'il faut revoir ce code, il y a quelque chose de pas net dedans. De plus, en cas d'impossibilité de créer l'objet voulu, les bonne pratiques veulent qu'on lance une Exception en java -> Une exception prend aussi du temps à être créée, beaucoup de temps
    Quelle différence de faire le check avant le new ou après ? Si ce n'est exécuté du code inutile ?


    En faite ce sont des règles auquel je n'adhère pas du tout mais qui avait été émise au temps de mes études par un enseignant pratiquant le C/C++. Les exceptions étaient alors reléguées à un paradigme inutile ...

  7. #7
    Membre régulier
    Profil pro
    Inscrit en
    Septembre 2006
    Messages
    287
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2006
    Messages : 287
    Points : 100
    Points
    100
    Par défaut
    D'après l'auteur, les avantages de passer par des fabriques statiques sont:
    • Elles possèdent un nom et ne sont (donc) pas limiter par leur signature. Le code du client est ainsi plus simple à lire et le risque d'invoquer le mauvais constructeur est réduit.

    • Elles ne sont pas obliger de créer un nouvel objet à chaque fois qu'elles sont invoquées.

    • Elles permettent d'envoyer un objet de tout type, ce qui permet de renvoyer tout classe qui est un sous-type de la classe concernée (par exemple, pour reprendre l'exemple de tchize_ public
      Code : Sélectionner tout - Visualiser dans une fenêtre à part
      Carre Rectangle.createCarre();

  8. #8
    Expert éminent sénior
    Avatar de adiGuba
    Homme Profil pro
    Développeur Java/Web
    Inscrit en
    Avril 2002
    Messages
    13 938
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Java/Web
    Secteur : Transports

    Informations forums :
    Inscription : Avril 2002
    Messages : 13 938
    Points : 23 190
    Points
    23 190
    Billets dans le blog
    1
    Par défaut
    Salut,


    Les fabriques ont des avantages c'est sûr... mais ce n'est pas une raison pour systématiser cela ! Dans bien des cas cela s'avère inutile...


    De plus le principe de la fabrique n'impose pas de passer le constructeur en private !!!


    a++

  9. #9
    Membre régulier
    Profil pro
    Inscrit en
    Septembre 2006
    Messages
    287
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2006
    Messages : 287
    Points : 100
    Points
    100
    Par défaut
    Juste pour info, quel problème cela pose-t-il de passer le constructeur en private?

  10. #10
    Expert éminent sénior
    Avatar de adiGuba
    Homme Profil pro
    Développeur Java/Web
    Inscrit en
    Avril 2002
    Messages
    13 938
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Java/Web
    Secteur : Transports

    Informations forums :
    Inscription : Avril 2002
    Messages : 13 938
    Points : 23 190
    Points
    23 190
    Billets dans le blog
    1
    Par défaut
    Cela empêche l'héritage puisque les classes filles ne peuvent pas appeler le constructeur parent.


    a++

  11. #11
    Membre expérimenté Avatar de Ivelios
    Homme Profil pro
    Développeur Java
    Inscrit en
    Juillet 2008
    Messages
    1 031
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : France, Ain (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur Java

    Informations forums :
    Inscription : Juillet 2008
    Messages : 1 031
    Points : 1 540
    Points
    1 540
    Par défaut
    La fabrique est pratique pour faire évoluer ton code.
    Si tu as une classa A par exemple (constructeur public)

    Tu fait une Factorie ( dans une classe apart) avec la méthode
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    createA(){return new A;}
    Quand tu veux un nouvelle objet A tu appel createA().

    L'avantage est que si tu souhaite passer à une version 2 -> classe AV2 extends A
    Tu as juste à modifier createA() : return new AV2;. Au lieu de parcourir tout ton code en modifiant new A par new AV2.

    Mais ci-dessus, c'est inutile

  12. #12
    Expert éminent sénior
    Avatar de tchize_
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2007
    Messages
    25 482
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : Belgique

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2007
    Messages : 25 482
    Points : 48 804
    Points
    48 804
    Par défaut
    Citation Envoyé par Nemek Voir le message
    Bouh le code pas beau
    Tu peux développer?
    Les exceptions ne sont pas les seuls mécanismes de gestion des erreurs.
    J'en conviens, mais c'est une bonne pratique de lancer une exception lorsque des circonstance exceptionnelle empechant de créer un objet existent. De plus, dans la plupart des cas, quand tu préfère renvoyer un null dans ta fabrique, ca finira chez l'appelant par un NullPointerException qui manquera des information sur pourquoi on ne peux pas créer l'objet!
    Quelle différence de faire le check avant le new ou après ? Si ce n'est exécuté du code inutile ?
    Faire le check avant nécessite justement de créer des méthodes supplémentaires, de dissocier éventuellement les check du comportement interne de la classe quand la fabrique se retrouve dans une classe tierce (ce qui est souvent le cas pour un fabrique créant des implémentations d'une interface). Le code lié au comportement interne de la classe doit rester dedans. Systématiser les fabriques à tout constructeur faisant un check, c'est multiplier les couches d'appel sur la stack, Si tu passe par uen fabrique pour créer un objet qui passe par une fabrique pour créer un autre objet qui passe par uen fabrique, .... Tu va avoir besoin de doubler la taille de la stack de la jvm . De plus, c'est risquer de compliquer le code, de multiplier les points à maintenir et donc probablement ralentir le développement, pour un gain bien marginal puisqu'il se produira dans des cas où vous aurez autre chose comme préoccupation que le temps perdu. (a savoir gérer le cas d'erreur).

    Il ne faut jamais optimiser comme ça (c'est à dire en changeant voir en risquant de compliquer l'architecture d'un code) sans avoir d'abord confirmation par des tests qu'il s'agit là d'un point chaud de votre application.


    @Ivelios: l'exemple ne montre aucun gain si il n'y a pas (cf mon exemple) de logique dans la factory pour le choix de la classe. En effet, si tout le code passe par createA() et qu'on faire un A2 (mise à jour) extends A, quelle différence cela fait-il avec faire partout new A() et simplement mettre la mise à jour directement dans A plutot que de faire un fils A2?

    Je rejoint adiguba: les factory on leur utilité, mais elles ne doivent pas être systématisée.

  13. #13
    Membre expérimenté Avatar de Ivelios
    Homme Profil pro
    Développeur Java
    Inscrit en
    Juillet 2008
    Messages
    1 031
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : France, Ain (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur Java

    Informations forums :
    Inscription : Juillet 2008
    Messages : 1 031
    Points : 1 540
    Points
    1 540
    Par défaut
    @Ivelios: l'exemple ne montre aucun gain si il n'y a pas (cf mon exemple) de logique dans la factory pour le choix de la classe. En effet, si tout le code passe par createA() et qu'on faire un A2 (mise à jour) extends A, quelle différence cela fait-il avec faire partout new A() et simplement mettre la mise à jour directement dans A plutot que de faire un fils A2?
    Je voyais A comme une classe appartenant à un programme non modifiable (jar ou autre). Mais effectivement, j'ai oublié de le préciser

Discussions similaires

  1. Mise à jour du modèle ne met pas à jour les méthode de fabrique
    Par killer_pingoui dans le forum Entity Framework
    Réponses: 2
    Dernier message: 15/01/2013, 15h56
  2. Méthode générique non static
    Par michelp3 dans le forum Langage
    Réponses: 9
    Dernier message: 20/12/2012, 00h30
  3. Générer méthodes de fabriques Interne
    Par metalsephiroth dans le forum Entity Framework
    Réponses: 4
    Dernier message: 04/04/2012, 20h03
  4. méthode private et static
    Par womannosky dans le forum Langage
    Réponses: 4
    Dernier message: 23/06/2008, 11h16
  5. [paint] Méthode déclaré en static
    Par Bugmaster dans le forum AWT/Swing
    Réponses: 5
    Dernier message: 23/08/2004, 15h51

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