62 votes

Le getter java enchaînant mal ou bien

Pour empêcher le monstre de constructeurs et monster interfaces avec trop de déléguer des classes, j'utilise beaucoup de classes qui contiennent d'autres objets qui, là encore, de contenir d'autres objets. Donc mon code ressemble à ceci beaucoup.

this.mainObject.getA().getAB().getABA().getABAC().doSomething();

Le style de vérification des paquets n'est pas compain à ce sujet et les métriques de couplage lâche sont OK. Je sais que c'est à cette question sur le chaînage de méthode, mais il n'est pas tout à fait le même que le getter de chaînage, sur lequel je peux trouver des petits conseils. C'est ma façon "correcte", ou est-il un meilleur modèle de conception? Ou est la vérité quelque part entre les deux, et l'on devrait utiliser enchaîné getters seulement si leur longueur est plus petite que p. ex. le 5?

Je suis à la recherche d'une meilleure pratique de style ou même un peu de style de la norme, si elles existent.

63voto

waxwing Points 10190

C'est mauvais d'un point de vue de la dépendance. this ne dépend pas seulement de la classe dans laquelle l' doSomething() est défini, mais aussi de tous les intermédiaires des classes. Les tests unitaires quelque chose comme ceci est un cauchemar, parce que vous finissez par avoir à se moquer de chaque classe intermédiaire.

En fait, il y a un principe appelé la loi de déméter qui dit que vous ne devriez appeler des méthodes sur vous-même, ou des objets qui vous sont directement liés.

55voto

Doug T. Points 33360

En plus de ce que les autres ont dit à propos des références nulles, vous avez bien sûr le Droit de Déméter. D'autres réponses ont fait un assez bon travail de décrire la Loi de Déméter, mais je pense que sa en vaut la clarification de certaines exceptions comme indiqué dans le Code Propre.

Selon Martin, la loi de déméter ne s'applique pas uniquement de données/structures (c'est à dire "struct like") de relations. IE Student.GetAddress().GetStreetName() est parfaitement acceptable. Martin fait les défenseurs de l'aide de la plaine des structures pour ces types de relations, mais, hélas, c'est Java. La Loi de Déméter toutefois, si vous avez participé mutateurs, ou fourni de l'écriture de l'accès à une classe interne avec des mutateurs ie Student.GetLastTest().ChangeGradeToA() devient de plus en plus problématique, car vous êtes probablement l'intention d'effectuer une opération sur l'Élève et qui pourrait facilement avoir un meilleur nom. En outre, vous sont étroitement associant le client de l'Étudiant, quelle que soit GetLastTest retourne.

Comme je l' avocat il est toujours conseillé de séparer proprement les données/relations structurelles de relations où une classe est de tenter d'agir sur l'autre.

28voto

Jesper Points 65733

Je n’appellerais pas cela un "mauvais style", ni quelque chose que j’appellerais "plus correct", mais l’un des problèmes avec une chaîne d’accessoires est que lorsque l’un d’eux retourne null , vous obtenir un NullPointerException et il peut être difficile de savoir lequel a retourné null .

17voto

Jack Edmonds Points 10264

Habituellement, cela est considéré comme une mauvaise pratique car il enfreint la loi de Demeter, qui stipule fondamentalement qu'au lieu d'enchaîner les getters, vous devriez avoir une méthode qui fait / obtient ce que vous voulez.

Le raisonnement derrière cette loi est

  1. Vous voulez que votre code soit associé de manière lâche à la mise en oeuvre de mainObject
  2. Essayer de simuler mainObject dans les tests unitaires devient soudainement extrêmement fastidieux.

4voto

user1132531 Points 51

Si, la plupart du temps, vous accédez à mainObject si vous appelez doSomething, le problème est lié au couplage. Peut-être qu'une méthode dans mainObject devrait renvoyer la valeur de doSomething .

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X