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 :

Cherche recommandations/normes d'écriture pour Java 1.6


Sujet :

Langage Java

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

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

    Informations forums :
    Inscription : Avril 2007
    Messages : 25 481
    Points : 48 806
    Points
    48 806
    Par défaut
    Citation Envoyé par gifffftane Voir le message
    Les possibilités d'évolution ne sont nullement cassées avec des attributs finaux publics, et c'est une légende urbaine que de dire qu'avec des getters et des setters elles sont facilitées.
    Je vais poser une question bete. Et je suis pas sur de la réponse, mais on sais faire de l'aop sur un attribut? Si demain, suite aux évolutions, une erreur analytique ou le changement d'avis d'un client, je décide que mon objet est trop lourd et que je désire que ses attributs soient initialisé en lazyloading, je dois remanier tous le code qui utilise l'attribut directement? Pour reprendre l'exemple de la voiture. Si on imagine un attribut "moteur", toutes les voitures on un moteur, n'est-ce pas? Aujourd'hui mon client me dit "ha mais attention, pour voir le moteur on doit absolument avoir le capot ouvert!" Je fais comment avec un attribut pour gérer ça?

    Je trouve que les getters/setters sont très pratique à utiliser, ne coutent pas plsu cher à développer que des attributs public et me laissent faire ce que je veux lors de l'accès (vérifer qu'on est bien dans un transaction, logguer l'accès si c'est une donnée confidentielle, vérifier que le capot est bien ouvert...) Certes dans 95% des cas mes getters se résume à un return. Mais les 5% ou j'ai besoin d'une évolution et ou j'ai besoin de revenir sur la propriété pour lui adjoindre un comportement suffisent largement à contrebalancer les 3 secondes que je met à cliquer dans mon IDE sur generate getters and setters.

    Attention cependant, je n'ai pas dit que tout devait avoir des getters et encore moins des setters. Ce qui doit rester privé, reste privé. Mais j'estime plus propre et plus évolutif de faire directement les getters / setters quand l'info est public. Pour ce que ca coute.

  2. #22
    Membre expérimenté
    Avatar de Patriarch24
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Septembre 2003
    Messages
    1 047
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

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

    Informations forums :
    Inscription : Septembre 2003
    Messages : 1 047
    Points : 1 640
    Points
    1 640
    Par défaut
    Making variables final prevents changing those values.
    Faux. C'est uniquement la référence qui est invariable.
    No setters(...) are they really necessary for your fields
    Là ok, mais pas de setter du tout... Comment on fait de l'injection de dépendance après ?
    Do not use loops for list operations.
    Perso, j'utilise Commons Collections pour les opérations sur les listes, en général. Mais pas toujours !
    Use Fluent Interfaces.
    Parfois pratiques (mocks, assertions de tests), parfois inutiles et rend le code invisible...
    Data Transfer Objects without setters and getters.
    No way. À moins que la classe soit finale. Cependant, si on change l'implémentation, faudra pas pleurer quand il faudra changer tout le code dépendant !
    Si une méthode ne doit pas être dérivé, elle doit bien sûr être final bien sûr !
    C'est justement ce à quoi ça sert. Il ne faut pas en abuser. D'ailleurs, à quoi cela sert de mettre final, si ce n'est empêcher que la méthode soit redéfinie ?

    Cet article donne des recommandations pour programmer en Java en utilisant un paradigme fonctionnel (Erlang est un langage fonctionnel, le concept de Closure - "pas de boucle" - est un concept fonctionnel, les valeurs immuables sont un concept fonctionnel...). Bref, en gros, pour bien programmer en Java, programmez fonctionnel. C'est discutable, pour ma part. Dans ce cas, autant faire du Ocaml (que j'adore), ou du Scala (que j'apprécie aussi) !
    En premier lieu, utilisez un moteur de recherche.
    En second lieu, postez sur le forum adéquat !

  3. #23
    Membre habitué
    Profil pro
    Développeur Java
    Inscrit en
    Juin 2009
    Messages
    102
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Java

    Informations forums :
    Inscription : Juin 2009
    Messages : 102
    Points : 172
    Points
    172
    Par défaut
    Citation Envoyé par adiGuba Voir le message
    [*]No setters.
    Là je ne suis pas d'accord du tout ! Cela implique qu'on ne devrait utiliser que des objets immuables !
    Or si ces derniers sont très utiles (ils permettent de partager des objets sans effet de bord), ils ne s'appliquent pas à tous les cas !

    Un exemple tout bête : sans "setter", tu serait obligé de totalement reconstruire ton interface graphique à chaque fois que tu veux modifier le moindre texte d'un label

    Les notions de classes immuables et de classes muables doivent exister conjointement, car elles représentent deux utilisations différentes.


    Enfin, je ne suis pas du tout d'accord concernant le fait de supprimer les "getters" pour les remplacer par des méthodes utilitaires. Cela limite forcément les cas d'utilisation...
    Moi je n'ai pas compris l'article en ce sens... Pour moi, ce que l'auteur dit, c'est que "donnée membre" n'équivaut pas à "getter / setter"... Un objet peut avoir une donnée membre pour sa tambouille interne sans que l'on ait forcément besoin de fournir la panoplie d'accès à cette donnée.
    En gros, réfléchis à quoi cette donnée membre sert...
    Bon, la phrase "Better create new copies of your objects if values change" est un peu bête cela dit...

  4. #24
    Membre régulier
    Profil pro
    Inscrit en
    Septembre 2008
    Messages
    71
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Septembre 2008
    Messages : 71
    Points : 90
    Points
    90
    Par défaut
    C'est justement ce à quoi ça sert. Il ne faut pas en abuser. D'ailleurs, à quoi cela sert de mettre final, si ce n'est empêcher que la méthode soit redéfinie ?
    En fait, je pense que le compilateur dans le cas d'une méthode final peut se permettre quelques optimisations. En effet, en java, toutes les méthodes sont par nature "virtual" au sens où on l'entend en C++. Ce qui signifie que toutes les méthodes donnent lieu à un pointeur de fonction dans l'équivalent de la vtable de l'objet (je ne connais pas les détails d'implémentation du bytecode Java mais on doit d'une manière ou d'une autre retrouver ces concepts). Un tel pointeur occupe d'une part (un peu) de place en mémoire et ensuite occupe (un peu aussi) du temps CPU puisque pour tout appel de méthode, on passe par cette indirection.

    Lorsqu'une méthode est final on doit, de manière théorique, pouvoir, au moins sur celles qui ne sont pas du tout dérivées, éviter cette indirection et linker directement sur l'adresse de la méthode au moment de la compilation plutôt que d'utiliser un pointeur de fonction.

    Ça n'est pas que le surcoût unitaire soit démesuré mais comme c'est multiplié par le nombre d'instances, le nombre de méthodes et le nombre d'appels réalisés sur ces méthodes, ça peut être significatif (d'ailleurs le surcoût du C++ par rapport au C se trouve essentiellement dans les implémentations "virtual").

    Ceci dit, je ne sais absolument pas si certains compilateurs tirent effectivement parti de cette possibilité et même si la norme du bytecode rend ça possible. J'essayerai de vérifier ça un jour...

  5. #25
    Membre habitué
    Inscrit en
    Juin 2009
    Messages
    138
    Détails du profil
    Informations personnelles :
    Âge : 36

    Informations forums :
    Inscription : Juin 2009
    Messages : 138
    Points : 159
    Points
    159
    Par défaut
    Citation Envoyé par adiGuba Voir le message
    [*]No setters.
    Là je ne suis pas d'accord du tout ! Cela implique qu'on ne devrait utiliser que des objets immuables !
    Or si ces derniers sont très utiles (ils permettent de partager des objets sans effet de bord), ils ne s'appliquent pas à tous les cas !

    Un exemple tout bête : sans "setter", tu serait obligé de totalement reconstruire ton interface graphique à chaque fois que tu veux modifier le moindre texte d'un label

    Les notions de classes immuables et de classes muables doivent exister conjointement, car elles représentent deux utilisations différentes.
    Entièrement d'accord. J'ajouterais même un argument, c'est la notion de contrôle d'affectation...
    Exemple tout simple : un attribut servant de diviseur pour une division... un setter permettrait de gérer le fait qu'il soit toujours différent de 0, au lieu de faire le contrôle à chaque affectation

  6. #26
    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
    Citation Envoyé par Yomhgui Voir le message
    • Le problème ne se poserait pas si la méthode en question attendait une List. Et en ce qui me concerne, je ne suis pas favorable à l'utilisation des classes de collection du JDK ailleurs que pour leur instanciation. Dans le code, il me semble nettement préférable d'utiliser les interfaces (Collection, List, Map, etc etc).
    +1
    Cela offre une meilleure abstraction et donc une meilleure réutilisation du code



    Citation Envoyé par Yomhgui Voir le message
    Mais ma vision de ce problème est que toute méthode n'a pas besoin d'être dérivée tant qu'elle ne l'a pas été. Si le besoin se manifeste, il peut être pris en charge rapidement. Ça n'a pratiquement aucun coût de supprimer un modificateur final puisque ça ne met pas le code en risque de régression. Et, si un besoin apparait dans ce sens, le fait de devoir supprimer un qualificateur existant à (l'énorme) mérite d'appeler une réflexion sur la pertinence de ce choix
    Je suis d'accord avec toi, mais cela n'est possible que pour un développement en interne où tu peux connaitre les besoins des développeurs.

    Dans le cas contraire tu risques de limiter ta librairie pour pas grand chose...

    Citation Envoyé par gifffftane Voir le message
    Les possibilités d'évolution ne sont nullement cassées avec des attributs finaux publics, et c'est une légende urbaine que de dire qu'avec des getters et des setters elles sont facilitées.
    Le problème en définissant un attribut public final, c'est que tu es obligé de le conserver sous cette forme quoi qu'il arrive : la moindre modification risque d'engendrer beaucoup de changement...

    Bien sûr pour des classes aux fonctionnalités limités (comme Point donné en exemple) ou pour des classes internes privées l'impact est limité. Mais dans des classes public destiné à être utilisé par tous cela risque de poser plus de soucis qu'autres choses...

    De plus tu parles de setter... mais il n'y a aucun moyen de modifier un attribut final !!!


    a++

  7. #27
    Nouveau membre du Club
    Homme Profil pro
    Développeur Web
    Inscrit en
    Mars 2009
    Messages
    32
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Canada

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : Communication - Médias

    Informations forums :
    Inscription : Mars 2009
    Messages : 32
    Points : 31
    Points
    31
    Par défaut
    Vous me faites bien rire!!!

    Est-ce que toute l'équipe a émit son opinion?

    Discussion très intéressante !

  8. #28
    Membre régulier
    Profil pro
    Inscrit en
    Septembre 2008
    Messages
    71
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Septembre 2008
    Messages : 71
    Points : 90
    Points
    90
    Par défaut
    Bon, la phrase "Better create new copies of your objects if values change" est un peu bête cela dit...
    Ça je suis bien d'accord. Re-instancier toute la voiture chaque fois qu'on tourne le volant de 2 degrés, c'est carrément inepte (pour reprendre l'exemple déjà utilisé). En cela d'ailleurs, je rejoins complètement l'avis de gifffftane sur les problèmes de mutabilité des objets. D'où mon avis (très) défavorable sur le point 2 du désormais fameux article.

    S'il fallait re-instancier une connexion chaque fois qu'on va envoyer un petit INSERT à une base de données, les performances des systèmes d'informations seraient dramatiques.

    Vous me faites bien rire!!!

    Est-ce que toute l'équipe a émit son opinion?
    Tu sais, vu l'impact beaucoup plus important qu'on ne l'imagine sur le coût des projets informatiques de ce genre de considérations, je crois qu'elles méritent largement d'être discutées et que l'expérience des uns et des autres peut être très profitable...

  9. #29
    Membre émérite
    Avatar de gifffftane
    Profil pro
    Inscrit en
    Février 2007
    Messages
    2 354
    Détails du profil
    Informations personnelles :
    Localisation : France, Loire (Rhône Alpes)

    Informations forums :
    Inscription : Février 2007
    Messages : 2 354
    Points : 2 582
    Points
    2 582
    Par défaut
    Citation Envoyé par tchize_ Voir le message
    Je vais poser une question bete. Et je suis pas sur de la réponse, mais on sais faire de l'aop sur un attribut? Si demain, suite aux évolutions, une erreur analytique ou le changement d'avis d'un client, je décide que mon objet est trop lourd et que je désire que ses attributs soient initialisé en lazyloading, je dois remanier tous le code qui utilise l'attribut directement?
    Oui, tu as raison, en tous cas avec spring. Mais il existe d'autres systèmes d'aop qui pistent les attributs. (même AspectJ je crois, c'est seulement la version Spring-aspectJ qui ne le fait pas)

    Si tes clients décident de la déclaration de tes attributs, alors il est parfaitement clair qu'il faut mettre des getters partout, mes propositions sont trop risquées.

    Dans l'ensemble, pour l'instant, après une petite année de pratique de cette idée, je n'ai jamais eu de problèmes. Je pense que c'est parce qu'il y a un couplage fort, assumé, entre objet et attribut, et que les évolutions concernent forcément les deux.

    En cette situation, plutot que de vouloir découpler ce qui est couplé, il est plus payant et souple de donner accès libre et visible aux composants, et en jouant sur la fiabilité de l'initialisation.

    C'est sur ce contexte que je peux répondre à tes différentes interrogations sur les lazy ou les droits de sécurité : il est vain de séparer les fonctions de lazy ou de sécurité d'un objet de son attribut en ce contexte de couplage fort, car l'accés à l'objet aura de grandes chances d'être très vite suivi d'un accès à l'attribut.

    Enfin, s'il apparait que la qualité public final par elle même était une erreur, alors je n'y peux rien ; quelques fois, la qualité de getter en est une aussi.

    Citation Envoyé par tchize_ Voir le message
    Pour reprendre l'exemple de la voiture. Si on imagine un attribut "moteur", toutes les voitures on un moteur, n'est-ce pas? Aujourd'hui mon client me dit "ha mais attention, pour voir le moteur on doit absolument avoir le capot ouvert!" Je fais comment avec un attribut pour gérer ça?
    Tout est possible, j'y vois une sorte de problème de MVC ; "on" est une vue, un utilisateur extérieur. Il a donc un modèle de la bagnole, modèle qui ne délivre le moteur que si "on" a ouvert le capot.

    Citation Envoyé par tchize_ Voir le message
    Je trouve que les getters/setters sont très pratique à utiliser, ne coutent pas plsu cher à développer que des attributs public et me laissent faire ce que je veux lors de l'accès (vérifer qu'on est bien dans un transaction, logguer l'accès si c'est une donnée confidentielle, vérifier que le capot est bien ouvert...) Certes dans 95% des cas mes getters se résume à un return. Mais les 5% ou j'ai besoin d'une évolution et ou j'ai besoin de revenir sur la propriété pour lui adjoindre un comportement suffisent largement à contrebalancer les 3 secondes que je met à cliquer dans mon IDE sur generate getters and setters.
    Et pourquoi ne pas réfléchir plus complètement à ces 5%, et à pourquoi 95% des getters se révèlent inutiles ? Pourquoi ne pas se poser la question ? Ces 5% d'utiles, c'est quoi ? C'est seulement que 5% du logiciel a évolué, que seulement 5% d'évolution a réussi, les getters c'est seulement pour l'évolution ?

    (en ce cas dernier cas il vaut mieux utiliser groovy je pense, et j'y réfléchis beaucoup en ce moment - autre évolution en cours d'étude)

    Ou bien - je me fais méchante langue - y aurait-il 95% de couplages forts dans nos applis, les getters et interfaces ne servant qu'à cacher la misère ?
    Mieux que Google, utilisez Sur Java spécialisé sur la plate-forme java !
    Pour réaliser vos applications Java dans le cadre de prestations, forfait, conseil, contactez-moi en message privé.

  10. #30
    Membre éclairé
    Profil pro
    Inscrit en
    Juillet 2007
    Messages
    802
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2007
    Messages : 802
    Points : 653
    Points
    653
    Par défaut
    Citation Envoyé par adiGuba Voir le message
    Pas forcément, perso j'utilise parfois quelque chose du style :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    public void method(MyObject value) {
        if (value == null) {
            value = DEFAULT_VALUE;
        }
     
        // utilisation de "value" qui n'est jamais null
    }
    Je préfère utiliser la surcharge pour définir des valeurs par défaut :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    public void method(MyObject value) {
        //code
    }
    public void method() {
        method(DEFAUL_VALUE);
    }
    Je trouve anormal la possibilité de passer des valeurs null à une méthode.

  11. #31
    Membre éclairé
    Profil pro
    Inscrit en
    Juillet 2007
    Messages
    802
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2007
    Messages : 802
    Points : 653
    Points
    653
    Par défaut
    Citation Envoyé par adiGuba Voir le message
    [*]No setters.
    Là je ne suis pas d'accord du tout ! Cela implique qu'on ne devrait utiliser que des objets immuables !
    Or si ces derniers sont très utiles (ils permettent de partager des objets sans effet de bord), ils ne s'appliquent pas à tous les cas !

    Un exemple tout bête : sans "setter", tu serait obligé de totalement reconstruire ton interface graphique à chaque fois que tu veux modifier le moindre texte d'un label

    Les notions de classes immuables et de classes muables doivent exister conjointement, car elles représentent deux utilisations différentes.


    Enfin, je ne suis pas du tout d'accord concernant le fait de supprimer les "getters" pour les remplacer par des méthodes utilitaires. Cela limite forcément les cas d'utilisation...
    Selon moi, l'idée que veux faire passer l'auteur est qu'une classe devrait clairement exposer ses responsabilités.

    En fait, on peut se retrouver devant deux possibilités :

    Soit la classe est un DTO ou un POJO et dans ce cas, les attributs devraient être public sans getter ni setter.

    Soit il s'agit d'une classe métier et dans ce cas, l'interface doit exprimer les responsabilités implémentées. Dans ce cas, un setter n'a pas lieu d'être.

    Par exemple, dans une Calculatrice, on implémente des fonctions pour additionner, soustraire, etc.. Il n'y a pas lieu d'avoir de setter

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

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

    Informations forums :
    Inscription : Avril 2007
    Messages : 25 481
    Points : 48 806
    Points
    48 806
    Par défaut
    Citation Envoyé par Kanithael Voir le message
    Pour moi, ce que l'auteur dit, c'est que "donnée membre" n'équivaut pas à "getter / setter"
    La je suis d'accord, pas besoin de getters / setter sur les membre privés qui doivent rester privé


    Citation Envoyé par Yomhgui Voir le message
    Lorsqu'une méthode est final on doit, de manière théorique, pouvoir, au moins sur celles qui ne sont pas du tout dérivées, éviter cette indirection et linker directement sur l'adresse de la méthode au moment de la compilation plutôt que d'utiliser un pointeur de fonction.
    Non, on est pas comme avec des librairies systme ici ou on va avoir une liste de symboles avec leur adresse d'utilisation et avoir le linker de l'os qui va passer su chacune de ces adresse mémoire pour y écrire l'adresse ou le symbole en question a été effectivement chargé.

    Si tu dis par exemple que la méthode finale machin() se trouve à 512 byte du début de la class X. tu serais tenté en tant que compilateur d'hardcoded "call adresseClass+512" au lieu d'un invokevirtual.... Seulement voilà, si moi je te fournis une nouvelle version de X demain, ben le 512 byte sera peut etre devenu 578! Et ton call voudra plus rien dire. On vois déjà ce problème avec les champs "public static final" sur les classes. Si j'utilise dans mon code un champ public static final (une "constante" donc) d'une classe tierce, puis que je recompile la classe tierce avec une nouvelle valeur sans recompiler mon code, mon code va utiliser l'ancienne constante (Il me semble, corrigez moi violement si je me trompe)

  13. #33
    Rédacteur
    Avatar de benwit
    Profil pro
    dev
    Inscrit en
    Septembre 2004
    Messages
    1 676
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : dev

    Informations forums :
    Inscription : Septembre 2004
    Messages : 1 676
    Points : 4 265
    Points
    4 265
    Par défaut
    Quelques petites questions ?

    Si void method(final Object var) { /* code*/ }; indique que la référence de var ne vas pas changer à l'intérieur de la méthode.

    Si on ne veut pas que ça change, c'est donc plus propre ?
    Mais à part le contrôle à la compilation, ça apporte autre chose ?

    Merci de vos réponses.

    Tout le monde savait que c'était impossible. Il est venu un imbécile qui ne le savait pas et qui l'a fait. Marcel PAGNOL
    On ne savait pas que c'était impossible, alors on l'a fait. John Fitzgerald KENNEDY.
    L'inexpérience est ce qui permet à la jeunesse d'accomplir ce que la vieillesse sait impossible. Paul (Tristant) BERNARD
    La meilleure façon de prédire l'avenir, c'est de l'inventer.

  14. #34
    Rédacteur
    Avatar de benwit
    Profil pro
    dev
    Inscrit en
    Septembre 2004
    Messages
    1 676
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : dev

    Informations forums :
    Inscription : Septembre 2004
    Messages : 1 676
    Points : 4 265
    Points
    4 265
    Par défaut
    Citation Envoyé par verbose Voir le message
    Je préfère utiliser la surcharge pour définir des valeurs par défaut :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    public void method(MyObject value) {
        //code
    }
    public void method() {
        method(DEFAUL_VALUE);
    }
    Je trouve anormal la possibilité de passer des valeurs null à une méthode.
    Il y a des cas ou la valeur null est possible
    Et à ce propos, dans les cas où null est indésirable, est-ce selon vous une bonne pratique de mettre assert(value != null) ?

    La surcharge que tu fais, je trouve ça élégant mais ...
    • si tu as plusieurs variables potentiellement null,
    • si la signature n'est pas disponible,
    • si tu utilises l'ellipse,

    comment fais tu ?

    Tout le monde savait que c'était impossible. Il est venu un imbécile qui ne le savait pas et qui l'a fait. Marcel PAGNOL
    On ne savait pas que c'était impossible, alors on l'a fait. John Fitzgerald KENNEDY.
    L'inexpérience est ce qui permet à la jeunesse d'accomplir ce que la vieillesse sait impossible. Paul (Tristant) BERNARD
    La meilleure façon de prédire l'avenir, c'est de l'inventer.

  15. #35
    Membre expérimenté
    Profil pro
    Inscrit en
    Mai 2004
    Messages
    1 252
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Mai 2004
    Messages : 1 252
    Points : 1 419
    Points
    1 419
    Par défaut
    Final is your new love: More and more Java developers in the teams I’ve worked with, started to use final. Making variables final prevents changing those values. Most often, if you reasign a value, it’s a bug or you should use a new variable. Final prevents bugs and makes code easier to read and understand. Make everything immutable.
    Pourquoi appeler cela une variable si elles sont toutes immuables ?

    Citation Envoyé par benwit
    Mais à part le contrôle à la compilation, ça apporte autre chose ?
    Non, à part le contrôle à la compilation, cela n'apporte rien. C'est comme les generics : à part mettre des marqueurs intéressant à la compilation, cela n'apporte rien ; c'est pareil avec les annotations qui ne sont pas utilisées au run-time : ça ne sert à rien techniquement parlant...

    Citation Envoyé par benwit
    Et à ce propos, dans les cas où null est indésirable, est-ce selon vous une bonne pratique de mettre assert(value != null) ?
    <mode avis personnel>
    Non. Ce genre de code n'est à placer que dans les méthodes privées. Pour éviter le null, mieux vaut une bonne vieille NullPointerException et une mention dans la javadoc. (La classe Preconditions de google-collections, quoiqu'extrêmement basique, est un excellent outil dans ce domaine.)

    En gros, tout ce qui est utilisable de l'extérieur doit être checké et doit renvoyer la RuntimeException appropriée (NPE, IllegalArgumentException, etc.) et tout ce qui est de la popote interne peut utiliser assert.
    </mode avis personnel>

    L'idéal reste toujours de lire Effective Java de fond en comble. Rien n'est à jeter dans ce livre et l'intérêt de beaucoup de conventions sont démontrées.

  16. #36
    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
    Citation Envoyé par dingoth Voir le message
    Pourquoi appeler cela une variable si elles sont toutes immuables ?
    La référence est invariable... mais l'objet référencé ne l'est pas forcément


    Citation Envoyé par dingoth Voir le message
    Non, à part le contrôle à la compilation, cela n'apporte rien. C'est comme les generics : à part mettre des marqueurs intéressant à la compilation, cela n'apporte rien ; c'est pareil avec les annotations qui ne sont pas utilisées au run-time : ça ne sert à rien techniquement parlant...
    Il me semble que la JVM peut optimiser les accès aux références qui ne sont pas modifiable. Donc pour un attribut final cela peut peut-être apporté quelque chose (mais c'est surement insignifiant).
    Pour un paramètre ou une variable locale, la JVM n'a pas besoin du mot-clef final pour déterminer si la référence est modifié ou pas... donc cela ne doit pas changer grand chose.

    Par contre cela peut permettre de créer des constantes locales, que le compilateurs pourraient évaluer dès la compilation...


    a++

  17. #37
    Membre expérimenté
    Profil pro
    Inscrit en
    Mai 2004
    Messages
    1 252
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Mai 2004
    Messages : 1 252
    Points : 1 419
    Points
    1 419
    Par défaut
    Je suis d'accord sur le fait que la référence n'est pas modifiée, bien entendu, mais ce genre de comportement sans réflexion conduit vite à du code illisible où l'on ne voit que du final partout et où l'on perd une logique parfois plus correcte.

    Exemple :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    public String normalize (final String string) {
      if (string == null) { throw new NPE(); }
      final String trimmedString = string.trim();
      if ("".equals(trimmedString)) { throw new IllegalArgumentException(); }
      final String lowerCasedTrimmedString = trimmedString.toLowerCase();
      final String alphaNumOnlyLowerCasedTrimmedString = lowerCasedTrimmedString.replaceAll("[^a-z0-9]+", "");
      return alphaNumOnlyLowerCasedTrimmedString;
    }
    Ce code est aberrant et doit être évité au maximum

    Là, en tapant le code, j'ai même failli faire une erreur importante en tapant la 5e ligne : string.toLowerCase(); au lieu de trimmedString.toLowerCase();

    Le même code en plus court et tout aussi correct :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    public String normalize (String string) {
      if (string == null) { throw new NPE(); }
      string = string.trim();
      if ("".equals(string)) { throw new IllegalArgumentException(); }
      return string.toLowerCase().replaceAll("[^a-z0-9]+", "");
    }
    Lequel est le plus lisible ? Lequel bouffera moins de mémoire ? Pour moi, y'a pas photo. Un final a chaque assingation signifie la fin de la lisibilité. Ce pseudo-site codemonkeyism dit tout : ce code est pour les singes, pas pour des programmeurs.

    P.S. @ Adiguba :
    Sa recommandation est : "make all immutable" !
    Ma recommandation est : "use your brain: use final when needed" !

  18. #38
    Membre éclairé
    Profil pro
    Inscrit en
    Juillet 2007
    Messages
    802
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2007
    Messages : 802
    Points : 653
    Points
    653
    Par défaut
    Il y a des cas ou la valeur null est possible[/B]
    Et à ce propos, dans les cas où null est indésirable, est-ce selon vous une bonne pratique de mettre assert(value != null) ?
    Ce que je veux dire, c'est que normalement on ne devrait jamais passer directement une valeur null à une méthode. Si un paramètre est potentiellement null, c'est qu'il est optionnel. Dans ce cas, il est préférable de fournir une surcharge sans ce paramètre et avec une valeur par défaut à null.

    Par ailleurs, je n'utilise jamais assert car les assertions ne permettent pas de controler le flux d'exécution d'un programme. J'aurais tendance à dire que la programmation par contrat n'est pas adapté à la POO, sauf à considérer une interface comme un contrat.

    • si tu as plusieurs variables potentiellement null
    • si la signature n'est pas disponible
    Il peut en effet se retrouver avec des méthodes qui prennent en paramètre plusieurs String par exemple :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    public void method(String s1, String s2, String s3) {}
     
    public void method(String s) {}
    Si s1, s2 et s3 sont tous les trois optionnels, on va se retrouver avec un conflit de signatures.

    Le problème peut être résolut en suivant les préconisations de codemonkeyism. Plutôt que d'utiliser des types communs, il faut typer les paramètres en fonction de leur sémantique :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
    public void method(Un un, Deux deux, Trois trois) {}
     
    public void method(Un un) {
        method(un, DEFAUL_VALUE, DEFAUL_VALUE)
    }
    public void method(Deux deux) {
        method(DEFAUL_VALUE, deux, DEFAUL_VALUE)
    }
    public void method(Trois trois) {
        method(DEFAUL_VALUE, DEFAUL_VALUE, trois)
    }
    [...]
    • si tu utilises l'ellipse
    Dans le cas de l'ellipse, ce principe n'est pas applicable en effet.

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

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

    Informations forums :
    Inscription : Avril 2007
    Messages : 25 481
    Points : 48 806
    Points
    48 806
    Par défaut
    Citation Envoyé par verbose Voir le message
    Ce que je veux dire, c'est que normalement on ne devrait jamais passer directement une valeur null à une méthode. Si un paramètre est potentiellement null, c'est qu'il est optionnel. Dans ce cas, il est préférable de fournir une surcharge sans ce paramètre et avec une valeur par défaut à null.
    Je ne suis pas entièrement d'accord. Ca peux rendre le code illisible. Fournir explicitement null à une méthode avec ce genre d'appel
    est effectivement mauvais dans bien des cas (pas tous), mieux vaux fournir un machin() sans arguments en plus. Par contre, je me vois mal écrire partout ce genre de code:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    Integer x = getMachin();
    Float y = getTruc();
    if (x==null && y==null)
       bidule();
    else if (x==null) 
       bidule(y);
    else if (y==null)
        bidule(x); 
    else
        bidule(x,y);
    alors que je peux mettre partout
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    bidule(getMachin(),getTruc())
    et faire une seule fois le test des null dans la méthode. D'ailleurs si je fournis un bidule sans argument, la pluspart du temps, il sera de a forme
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    public void bidule(){
        bidule(null,null);
    }
    avec getMachin et getTruc étant différent probablement suivant les emplacements

  20. #40
    Membre régulier
    Profil pro
    Inscrit en
    Septembre 2008
    Messages
    71
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Septembre 2008
    Messages : 71
    Points : 90
    Points
    90
    Par défaut
    Citation Envoyé par tchize_ Voir le message
    Non, on est pas comme avec des librairies systme ici ou on va avoir une liste de symboles avec leur adresse d'utilisation et avoir le linker de l'os qui va passer su chacune de ces adresse mémoire pour y écrire l'adresse ou le symbole en question a été effectivement chargé.

    Si tu dis par exemple que la méthode finale machin() se trouve à 512 byte du début de la class X. tu serais tenté en tant que compilateur d'hardcoded "call adresseClass+512" au lieu d'un invokevirtual.... Seulement voilà, si moi je te fournis une nouvelle version de X demain, ben le 512 byte sera peut etre devenu 578!
    En effet. Ceci étant dit, ce problème ne se pose qu'aux interfaces entre différentes librairies. Dans une archive donnée, par nature recompilée en intégralité à chaque fois, il y a quand même tout un tas de cas où on peut savoir en analysant la portée des éléments s'il sont susceptibles d'être appelés en dehors de la librairie. Toutes les classes qui sont de portée "package protected", les méthodes "package protected" ou "private" (ceci dit, finaliser les méthodes private présente un intérêt... totalement nul) les "inner classes" qui sont privées où "package protected" (voir même protected ou public si elles sont déclarées dans une classe dont la portée est elle même limitée), sont d'un usage qui est limité dans une archive donnée et qui ne souffre pas du souci que tu évoques, fort justement d'ailleurs.



    -------
    Heuuuuu...
    Après réflexion sur ce que je viens d'écrire, il est vrai qu'on est pas obligé de livrer un appli sous forme de jar et que le compilateur ne sais de toutes façons pas comment le livrable va être packagé. Bon, ça réduit le champ d'application aux classes package protected et aux classes internes privées ou package protected. C'est déjà pas si mal.

Discussions similaires

  1. Cherche une API de report pour JAVA
    Par MaxLaMenaX dans le forum Documents
    Réponses: 6
    Dernier message: 10/04/2009, 08h54
  2. Cherche un outil de reporting comme BIRT pour Java
    Par tiboudchou dans le forum Autres outils décisionnels
    Réponses: 4
    Dernier message: 02/01/2007, 14h25
  3. Votre EDI préferé pour Java (2003-2004) ?
    Par christopheJ dans le forum EDI et Outils pour Java
    Réponses: 73
    Dernier message: 17/10/2005, 17h05
  4. Réponses: 4
    Dernier message: 16/10/2005, 18h30
  5. Profiler pour Java
    Par donde dans le forum Tests et Performance
    Réponses: 1
    Dernier message: 10/02/2003, 17h36

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