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 :

Conventions sur les getters


Sujet :

Langage Java

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Profil pro
    Inscrit en
    Février 2008
    Messages
    43
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2008
    Messages : 43
    Par défaut Conventions sur les getters
    Bonjour à tous,
    une question concernant les conventions sur les getters qui je l'espère n'est pas trop bête. Voilà : y-a-t-il une convention qui dit qu'un getter doit renvoyer une référence sur l'objet demandé ?
    Je m'explique par un exemple
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    public void getPosition(int i, Vector3d pos){
        post.set(_pos[i]);
    }
    où, vous l'aurez compris, _pos est un Vector3d[]. Est-il correct d'appeler cette méthode getPosition, ou bien vaudrait-il mieux indiquer explicitement qu'elle renvoie une copie, par exemple copyPosition(int i, Vector3d pos)

    Vos lumières sont les bienvenues ! Merci d'avance,
    Sébastien

  2. #2
    Membre confirmé
    Profil pro
    Inscrit en
    Juin 2007
    Messages
    42
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France

    Informations forums :
    Inscription : Juin 2007
    Messages : 42
    Par défaut
    Bonjour,

    Effectivement, la convention stipule qu'un getter de propriété renvoie l'objet demandé (ça paraît si logique en le disant), et qu'il ne prend pas de paramètre.
    S'il en prend, ce n'est plus à proprement parler un getter, puisqu'il ne sert alors pas à récupérer la valeur d'une propriété au sens JavaBean. En revanche, il reste juste de l'appeler "get...".

    Dans ton cas par contre, en plus du fait que ta méthode n'est pas du tout un getter (elle écrit dans une variable membre), le nom "getPosition" est très mal choisi, car il ne montre pas du tout ce que fait la méthode. Quand on lit ce nom, on s'attend tout naturellement à récupérer une position, et surtout pas à modifier une variable membre. "copyPosition", c'est mieux, beaucoup mieux .

  3. #3
    Membre averti
    Profil pro
    Inscrit en
    Février 2008
    Messages
    43
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2008
    Messages : 43
    Par défaut Un follow-up
    Merci Eric !
    Je n'utilise pas Javabeans (je fais du calcul scientifique avec Java), et je n'avais pas réalisé que la notion de Getter/Setter provenait de Javabeans. Je devrais peut-être me cultiver à ce sujet pour ne pas écrire de programmes qui vont à l'encontre de conventions bien établies.
    Il y a une question subsidiaire. Je renvoie une copie de la position de la particule, car on ne peut modifier celle-ci sans procéder à des vérifications préalables. Et le fait de passer en paramètre le Vector3d à modifier me permet d'économiser un new. Jusque là, tout va bien.
    Ma question est : que pensez-vous de la solution (pas mal utilisée je crois dans java.nio) suivante
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    public Vector3d getPosition(int i, Vector3d pos){
        pos.set(_pos[i]);
        return pos;
    }
    Cela permet le chaînage des instructions, mais personnellement, je trouve que cela induit un peu en erreur. Qu'en pensez-vous ?
    Merci par avance,
    Sébastien

  4. #4
    Membre averti
    Profil pro
    Inscrit en
    Février 2008
    Messages
    43
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2008
    Messages : 43
    Par défaut Et l'encapsulation ?
    Bonjour,
    suite à la réponse précédente d'Eric, je me pose une nouvelle question.
    J'imagine que l'intérêt pour un getter de renvoyer une référence vers l'objet est de pouvoir modifier l'état de cet objet. Mais cela ne suppose-t-il pas que l'on fait une hypothèse sur l'implémentation ?
    Je m'explique, en reprenant l'exemple précédent. Supposons que les positions de mes particules soient stockées dans un tableau Vector3d[]. Si j'implémente le getter sous la forme
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    public Vector3d getPosition(int i){
        return _pos[i];
    }
    Alors, lorsque je fais
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
        pos = simulation.getPosition(i);
        pos.x = 0.0;
    j'ai effectivement modifié l'état de l'objet simulation.

    En revanche, si les positions avaient été stockées dans trois double[], et si j'avais implémenté le getter sous la forme
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    public Vector3d getPosition(int i){
        return new Vector3d(_x[i], _y[i], _z[i]);
    }
    je ne serais plus capable de modifier l'état de ma simulation par un simple appel au getter.
    Il me semble donc que le principe d'encapsulation est violé, non ?
    Ou alors, il y a un autre principe qui dit que je DOIS appeler le setter pour m'ASSURER que l'état est changé (même si certaines implémentations pourraient me permettre de me dispenser d'un tel appel).
    Merci de vos réponses,
    Sébastien

  5. #5
    Membre confirmé
    Profil pro
    Inscrit en
    Juin 2007
    Messages
    42
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France

    Informations forums :
    Inscription : Juin 2007
    Messages : 42
    Par défaut
    Bonjour,

    Alors, pour répondre à ta première réponse, JavaBeans est une convention toute simple qui vise juste à permettre à des applications de manipuler des objets par introspection. Dans 95% des cas, cette convention est utile pour les EDI qui proposent des designers d'interface. En effet, quand on sélectionne un composant graphique dans un designer, on a toujours une fenêtre qui permet de modifier ses propriétés. Et en général, une propriété correspond à une paire getter/setter (ou seulement getter si elle est en lecture seule) sur l'objet qui représente le composant. Donc, pour permettre aux EDI de manipuler ces composants graphiques, la convention JavaBeans est apparue et dit seulement qu'un objet Java est un JavaBean s'il possède un constructeur par défaut (pour que les EDIs puissent l'instancier facilement) et si, pour une propriété "abc" (toujours en minuscule), son getter est "Type getAbc()", et son setter est "void setAbc(Type abc)".

    Cette convention a été largement adoptée au-delà du concept de JavaBean, et il est quasiment de rigueur de nommer ses accesseurs ainsi. Mais dans ton cas, même sans parler de la moindre convention, le nom "getPosition" ne convient vraiment pas pour ta méthode, car il viole un principe universel en programmation : le principe de moindre surprise. Le nom parle de lui-même. Et en l'occurrence, comme je l'ai dit dans ma première réponse, le comportement de la méthode va être une surprise pour quiconque l'utilisera, au vu de son nom.

    Ensuite, concernant ta "question subsidiaire", le fait de permettre le chaînage de méthodes est un de ces sujets qui font couler beaucoup d'encre. C'est extrêmement subjectif. En ce qui me concerne, je suis très attaché à la sémantique de ce que j'écris, bien plus qu'à sa "praticité". Pour moi, c'est beau quand c'est logique et simple, quitte à ce que ce soit un peu plus verbeux. Or le chaînage de méthodes est certes simple, mais il oblige à faire une entorse à la sémantique d'une méthode pour obtenir un effet syntaxique. D'autant que cet effet n'est, à mon sens encore une fois, pas très esthétique.

    Concernant ta deuxième réponse maintenant, tu poses une question très intéressante. Mais ce qui est bien, c'est que tu y as répondu parfaitement tout seul . Effectivement, il te faut un setter. Et comme tu le dis, il est bon de toujours appeler un setter, justement pour éviter d'avoir à se poser cette question. Ainsi, ton implémentation peut être quelconque, l'utilisateur voit toujours des positions au travers de Vector3d, aussi bien pour les récupérer que pour les définir.

    Ceci soulève un autre point intéressant : tu as deux possibilités pour ton setter :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    void setPosition(int i, int x, int y, int z)
    ou
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    void setPosition(int i, Vector3d position)
    Les deux possibilités ne sont pas équivalentes. En effet, dans le premier cas, ton setter ne dépend pas de Vector3d (ce qui réduit le couplage entre les deux classes). Par contre, si on imagine qu'un jour une position puisse nécessiter une information supplémentaire (certes l'exemple n'est pas très bon pour ce cas), tu seras obligé d'ajouter un paramètre à ta méthode, et donc de reprendre tous les appels pour les corriger. Avec la deuxième solution, tu introduis une abstraction supplémentaire, ce qui est bénéfique puisque le code qui utilise le setter ne dépend plus de ce en quoi consiste une position.

    En espérant t'avoir éclairé .

  6. #6
    Membre Expert
    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
    Par défaut
    Une autre possibilité est le changement de nom de la méthode :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    public void fillPosition (int i, Vector3D post) {
      post.set(_pos[i]);
    }

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Convention sur les commentaires
    Par bedomon dans le forum Langage
    Réponses: 2
    Dernier message: 15/10/2013, 16h42
  2. Caractères spéciaux dans les tags XML : soucis sur les getters
    Par schtroumpfNormand dans le forum Services Web
    Réponses: 4
    Dernier message: 09/08/2011, 14h06
  3. Réponses: 1
    Dernier message: 03/12/2010, 22h00
  4. Réponses: 5
    Dernier message: 01/03/2010, 16h01
  5. Convention sur les codes de retour des scripts
    Par NewTone dans le forum Linux
    Réponses: 0
    Dernier message: 19/11/2009, 00h54

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