Est-ce une odeur de code si une méthode privée appelle une méthode publique?


25

Est-ce une odeur de code d'appeler une méthode publique dans une méthode privée de la même instance d'objet?


AAMOI avez-vous un exemple précis?
ocodo

Non, pas actuellement. Je viens de me souvenir d'un cas dont j'ai discuté avec mes collègues. Je voulais aussi avoir des opinions ici.
Eimantas

5
Habituellement, je peux trouver un acronyme par le contexte, mais AAMOI, je devais certainement chercher
Carson Myers

@Carson - avez-vous trouvé quelque chose?
Eimantas

4
Comme une question d'intérêt
Carson Myers

Réponses:


32

Pas une mauvaise odeur. Cela pourrait être nécessaire, pourquoi pensez-vous que c'est faux? Une méthode au niveau atomique est une entité indépendante qui effectue une tâche. Tant qu'il exécute une tâche, toute personne qui y a accès peut l'appeler pour effectuer la tâche.


Je suis d'accord. Certaines méthodes fournissent des fonctionnalités utiles à la fois pour les internes et pour les appelants externes. Un drapeau rouge pourrait être si la méthode publique était très spécifique à l'implémentation interne, mais même dans ce cas, toutes les classes ne sont pas destinées à masquer ses internes. J'ai souvent une couche "outil" de structure de données sous une couche de type abstrait de conteneur, par exemple - de cette façon, je peux réutiliser une partie du code de structure de données pour d'autres structures de données sous-jacentes à d'autres conteneurs.
Steve314

19

Odeur de code? Oui, pas vraiment mauvais, mais un bon indicateur que la classe peut avoir trop de responsabilités.

Prenez-le comme un signe que la classe peut avoir besoin d'être divisée en différents objets, les méthodes privées ne devraient pas vraiment avoir besoin d'appeler des méthodes publiques du même objet, certainement dans une conception OO propre.

Bien sûr, une fois que vous avez inspecté la classe et que les raisons de l'appel de méthode sont claires, cela peut être une utilisation parfaitement raisonnable, en général, vous vous attendez à ce que les méthodes utilitaires pour la classe soient privées, mais si l'une est suffisamment utile pour être publique et utilisée par d'autres méthodes, je m'attendrais généralement à ce que ces méthodes soient publiques également.

Comme pour toutes les odeurs de code, c'est une motivation pour une inspection plus approfondie du code, une rationalisation et peut-être une refonte, mais pas une cause d'alarme.


5
+1 pour «pas une cause d'alarme». Trop souvent, nous voyons une «odeur» et passons instantanément en mode refactor sans réfléchir.
Michael K

+1 pour SRP. Je suis juste tombé sur un cas où un décorateur ne travaillait pas parce que la classe décorée appelait sa propre fonction publique, contournant le décorateur. La solution: divisez la classe en deux et injectez la dépendance décorée.
Jon Hulka

18

Cela peut entraîner des surprises désagréables si quelqu'un qui n'a pas lu le code source de cette classe essaie de le sous-classer et remplace la méthode publique. La question de savoir si cela est réel dépend évidemment de votre situation. Vous devriez peut-être envisager de rendre la méthode publique ou même la finale de la classe.


Pourquoi? Si une méthode publique écrasée entraîne des surprises désagréables, est-ce vraiment important qui a appelé la méthode?
user281377

4
Oui. Si le remplacement d'une méthode publique rompt une autre méthode publique, je peux également remplacer cette autre méthode. Si ça casse une méthode privée, je peux ....?
Kim

5
Une surprise désagréable résultant du remplacement d'une méthode publique est une odeur de code en soi. Une puanteur de code, en fait.
Larry Coleman,

Kim: si la méthode est publique, vous devez supposer que les autres classes appellent aussi cette méthode ...
user281377

@ Larry: Exactement! Une méthode privée (qui contient généralement des hypothèses spécifiques à l'implémentation) appelant une méthode publique rend plus probable que le remplacement de la méthode publique casserait les choses.
Kim

5

Je ne pense pas que nous puissions généraliser.

Tout dépend très fortement du contexte.

Je pourrais avoir, disons, une méthode d'utilité publique dans une classe qui est utilisée par d'autres classes, et aussi une méthode privée dans la même classe.


5

Non. Que faut-il faire d'autre dans ce cas? Rendre la méthode privée publique ou la méthode publique privée? Copiez-collez le code de la méthode publique vers la méthode privée?


Ou demandez à la méthode publique de déléguer à une (nouvelle) méthode privée qui est invoquée par l'autre méthode privée. Mais pourquoi s'embêter?
Lawrence Dol

4

NON , pas de mauvaise odeur ici.

si nous implémentons l'interface d'une file d'attente avec List, est-ce une mauvaise odeur d'appeler simplement les fonctions List appropriées afin de réaliser facilement l'implémentation de la file d'attente?

si vous avez quelque chose et que vous voulez le convertir en quelque chose d'autre (comme un wrapper), ce n'est pas une mauvaise odeur, sa réutilisation du code avec le modèle de conception a agi au niveau de la fonction (une fonction est-elle un objet?)


2

Je sais que c'est un ancien poste, mais c'est quelque chose dont j'ai débattu au travail. Je «considère» cela comme une odeur de code, et je ne comprends pas pourquoi vous voudriez faire cela. Si une méthode privée doit appeler une méthode publique, le contenu de la méthode publique doit être pris et placé dans une méthode privée, que les deux méthodes peuvent ensuite appeler. Pourquoi?

  1. La méthode publique peut contenir des tests qui ne sont pas nécessaires une fois votre code exécuté en interne. Il peut recevoir un UserObj et vouloir tester les autorisations des utilisateurs par exemple.

  2. Après un appel public, vous devrez peut-être verrouiller l'objet, si vous utilisez le threading, donc en interne, vous ne voudrez pas rappeler à une méthode publique.

  3. Plus susceptibles d'introduire des erreurs circulaires et des boucles infinies et des exceptions hors mem à mon avis.

  4. Simple et simplement, mauvais design et "paresseux". Les méthodes publiques permettent d'accéder au monde extérieur. Il n'y a aucune raison de retourner à l'extérieur lorsque vous êtes déjà à l'intérieur.


1
Que faire si la méthode publique existante est appelée par de nombreuses autres classes? Le rendre privé rompra cela. N'oubliez pas que les méthodes publiques sont appelées par d'autres classes pour d'autres raisons, pas seulement cette classe. un peu pourquoi les méthodes publiques existent.
Michael Durrant

J'ai déclaré que «le contenu de la méthode publique doit être pris et placé dans une méthode privée ...» La méthode publique restera, mais appelez la nouvelle méthode privée. Comme toutes les autres méthodes privées qui doivent réutiliser les mêmes fonctionnalités.
Mark Graham

Vous ajoutez donc une autre méthode pour aucune autre raison que - eh bien, parce que vous avez déclaré que c'était une "odeur de code". Les méthodes inutiles sont une odeur de code pire.
gnasher729

Désolé, mais n'ai-je pas simplement énuméré plusieurs raisons ci-dessus. Une grande partie du code que j'écris est pour les systèmes d'entreprise, de nombreuses classes sont limitées aux utilisateurs en fonction du rôle. De nombreuses méthodes publiques testent les autorisations et les paramètres des utilisateurs. Pourquoi diable voudrais-je rappeler la même méthode publique pour réutiliser ses fonctionnalités et tester à nouveau les autorisations utilisateur?
Mark Graham

Je n'ai jamais dans ma vie eu besoin d'appeler une méthode publique à partir d'une méthode privée. Cela me semble et me semble très mal. Je suis vraiment surpris que la plupart des gens pensent que ça va.
Piège

2

Imaginez le contraire. Vous êtes dans une méthode privée et vous avez besoin de fonctionnalités dans une méthode publique Et si vous ne pouviez pas appeler cette méthode publique à partir de la méthode privée. Qu'est-ce que tu ferais?

  • Créer une méthode privée en double? Non
  • Créer une méthode publique spéciale pour l'occasion? Non
  • Appeler une méthode privée spéciale qui peut appeler des méthodes publiques? Non
  • Une sorte de super qui peut faire ça? Non

La réponse est clairement que lorsque vous voulez la fonctionnalité dans une méthode publique, vous devriez pouvoir appeler cette méthode à partir des méthodes de cette classe ou d'autres classes.


1

Dans mon code, je crée souvent des getters de chargement paresseux, c'est-à-dire que l'objet est initialisé la première fois qu'il est demandé et réutilise ensuite le même objet instancié. Cependant, un objet instancié à l'aide d'une charge différée implique qu'il ne peut pas nécessairement être instancié à un moment donné. Plutôt que d'enrouler ma tête autour de la séquence d'appels de telle sorte que je sache que cet objet est déjà instancié ou répète le même code d'un chargement paresseux dans une autre méthode, j'appelle simplement le chargeur paresseux chaque fois que j'ai besoin de cet objet.

Tout comme vous pouvez utiliser les méthodes publiques de manière intelligente, vous pouvez également les utiliser de manière incorrecte. Un exemple de ceci pourrait être une méthode publique qui traite ses paramètres avant d'appeler une autre méthode privée. Ce serait une erreur d'appeler cette méthode publique nonchalamment simplement parce que vous avez les mêmes paramètres. L'erreur est subtile mais c'est une erreur de conception plus que toute autre chose et nécessite que vous appreniez à gérer avec les paramètres de la méthode interne plutôt qu'avec les paramètres de la méthode publique.

Donc, pour répondre à votre question, ce n'est certainement pas un mauvais code si vous l'utilisez correctement.


1

La question que vous devez vous poser est pourquoi votre classe a-t-elle le même besoin que les clients de votre classe? Habituellement, une classe a des besoins très différents de ses clients. Alors oui, c'est une indication que vous avez soit

(a) exposé publiquement quelque chose qui devrait être privé; ou

(b) le comportement de la classe n'est pas assez étroit (pensez au principe de responsabilité unique).

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.