Qu'est-ce qui ne va pas dans le retour de la table de hachage à partir de la méthode publique et quand est-il judicieux de le faire?

9

Quels sont les problèmes de conception liés au renvoi d'une table de hachage à partir d'une méthode publique lorsque vous souhaitez renvoyer plusieurs éléments au lieu de créer une classe et d'en renvoyer un objet?

S'il a des problèmes, dans quelles circonstances est-il logique de le faire?

Comment la réponse à cette question change-t-elle selon que la langue est dynamique ou non?

Modifier: c'est pour clarifier que les clés seraient constantes et font partie du code, pas des données. Quelque chose pour lequel nous créons généralement une classe. La question est de savoir pourquoi serait-il mal d'utiliser la table de hachage à la place si la création d'une classe semble effectivement être le bon choix.

Muhammad Hasan Khan
la source

Réponses:

11

Utilisez une classe mieux définie comme type de retour qu'une table de hachage qui contient un nombre arbitraire de valeurs sous forme de paires nom / valeur.

  1. Le premier et le plus important point est - Maintenabilité. En regardant le code, un nouveau programmeur ne peut jamais dire quelles sont les valeurs que la méthode retourne. Si une nouvelle personne ne comprend pas cela en regardant le code, le code ne sera pas utile et sujet à des erreurs chaque fois que quelqu'un va ajouter plus de clés / valeurs à ces données ou améliorer l'application.

  2. Les méthodes sont des contrats entre l'appelant et le service. La chose la plus importante dans une méthode est leur entrée et leur sortie. Ces entrées et sorties doivent être facilement lisibles, compréhensibles et auto-documentées. Si vous utilisez une classe Person comme valeur de retour qui a un prénom, un nom de famille, un âge - Elle est auto-documentée. Si vous générez un Javadoc pour cela, l'utilisateur peut naviguer entre les classes pour mieux le comprendre. Si vous utilisez une table de hachage, vous devez l'expliquer dans les commentaires que personne ne lira ou mettre à jour lorsque les choses changeront.

  3. Vous ne pouvez pas utiliser de génériques comme HashMap<String,String>dans le cas si vous souhaitez ajouter un nombre (par exemple, l'âge) à la déclaration de retour. Si vous n'utilisez pas de génériques, vous devrez effectuer un va-et-vient entre l'objet et le type réel. Vous pouvez l'enregistrer si vous utilisez la saisie dynamique.

  4. De plus, il y a plus de chances d'échec d'exécution que d'attraper des problèmes lors de la compilation. Par exemple, si quelqu'un supprime une entrée de la table de hachage et qu'un des anciens appelants attend l'entrée, le client échoue pendant l'exécution. Il est toujours préférable d'attraper ce problème lors de la compilation.

  5. Il sera difficile de renvoyer un type immuable si vous souhaitez utiliser hashmap comme type de retour et ainsi de suite. Mais si vous utilisez un utilisateur défini votre propre type, vous pouvez contrôler cela.

Il sera tentant d'utiliser un hashmap comme type de retour car vous pouvez éviter de créer quelques classes au début, mais ce sera un cauchemar de maintenir le code à l'avenir. Allez orienté objet !!!!

java_mouse
la source
1
Vous semblez avoir bien compris la question. Merci.
Muhammad Hasan Khan
8

L'un des problèmes serait que dans de nombreux cas, la clé de la table de hachage serait une chaîne. Ainsi, les consommateurs de la méthode devraient savoir à l'avance quelles clés utiliser pour extraire les données. Cela donnerait le potentiel d'erreurs dues à des fautes d'orthographe lors de l'accès aux données.

Un autre inconvénient est la refactorabilité. Si vous décidez plus tard de changer le nom d'un membre, vous avez alors un tas de cordes magiques qui doivent également changer. Il est beaucoup plus simple de renommer un membre de la classe à l'aide des outils de refactoring fournis par la plupart des bons IDE. Avec une table de hachage, vous devrez probablement effectuer une opération de recherche / remplacement dans tous les fichiers source, ce qui pourrait être problématique.

Enfin, vous perdrez le temps de compilation pour vérifier l'accès des membres - à la fois en termes de nom et de type. Ce dernier n'est pas un problème si votre table de hachage ne contient qu'un seul type d'objet, mais s'il en contient plusieurs (même dans la même chaîne de hiérarchie), vous voulez vraiment tirer parti du système de types de votre langue et y obtenir du temps de compilation. Dans la plupart des IDE, vous aurez une sorte de fonctionnalités d'intellisense / de saisie semi-automatique - celles-ci fonctionnent en regardant le système de type, mais elles ne pourront pas vous aider avec les clés de table de hachage.

En ce qui concerne les moments où il serait approprié de renvoyer une table de hachage (ou une autre collection de paires de valeurs de clés), vous l'utiliseriez lorsque les valeurs et les clés ne sont pas connues au moment de la compilation. Par exemple, si vous avez une méthode qui analyse une chaîne de requête et renvoie les clés et les valeurs correspondantes, une table de hachage serait un bon choix. Dans ce cas, vous voudrez également penser à renvoyer une sorte de table de hachage immuable ou en lecture seule.

Modifier - La plupart des points soulevés dans cette réponse ne s'appliquent plus lorsque vous parlez de langues dynamiques :)

MattDavey
la source
Et si la langue est dynamique?
Muhammad Hasan Khan
Je ne suis pas un expert en langues dynamiques, donc quelqu'un d'autre peut probablement fournir une meilleure réponse à cela. Mais je sais que les langages dynamiques ne compilent pas la vérification du type de temps de toute façon. Mais dans ce cas, le retour d'un objet et le retour d'une table de hachage ne sont pas si différents ..
MattDavey
3
@Hasan Khan: Dans ce cas, il peut ne pas y avoir de différence entre une table de hachage et une instance de classe. Par exemple, en Javascript, tous les objets sont des tables de hachage, et object.property est exactement la même chose que object ['property']
Michael Borgwardt
"Avec une table de hachage, vous devrez probablement effectuer une opération de recherche / remplacement dans tous les fichiers source, ce qui pourrait être problématique." Seulement si vous avez choisi des clés médiocres et que vous n'avez jamais essayé de factoriser les clés standard pour qu'elles soient définies en un seul endroit…
Donal Fellows
7

L'argument le plus important contre cela serait que vous exposez trop d'informations au consommateur. Le code consommateur a seulement besoin de savoir qu'il s'agit d'une collection clé-valeur (dictionnaire) d'une certaine sorte; qu'il soit implémenté sous forme de table de hachage, de liste d'association, de trie ou autre, est relativement peu intéressant. Donc, la bonne façon serait de retourner par une interface appropriée ( IDictionary, ou quelle que soit la langue de votre choix) plutôt que par type réel.

Tout cela en supposant que vous avez réellement besoin d'un dictionnaire pour représenter vos données, c'est-à-dire que vos données sont constituées de paires clé / valeur, où les clés sont uniques parmi l'ensemble de données et ne peuvent pas être corrigées au moment de la compilation. Si vous avez des clés pré-connues, vous devez créer un type approprié (ou plusieurs, selon les besoins) pour vos données. Il s'agit de savoir si vous considérez les clés elles-mêmes comme faisant partie des données ou comme faisant partie du code.

MODIFIER :

Pour clarifier, j'utilise ici le terme dictionnaire pour désigner le type le plus générique de structure de données de valeur-clé; Je ne veux pas dire d'implémentation spécifique au langage comme Python dictou .NET Dictionary.

tdammers
la source
1
+1 pour "Il s'agit de savoir si vous considérez les clés elles-mêmes comme faisant partie des données ou comme faisant partie du code." - C'est une bonne façon de le dire. Je ne sais pas dans quelle mesure le terme «dictionnaire» est universel par opposition à «carte» par exemple.
MattDavey
Le retour du dictionnaire n'était pas prévu. les clés faisaient partie du code et non des données.
Muhammad Hasan Khan
La vraie question est le raisonnement derrière «vous devriez créer un type approprié». La question est pourquoi?
Muhammad Hasan Khan
2

Une question que je me poserais est "les clés changent-elles dans ce dictionnaire?" S'ils sont constants, vous devez renvoyer un objet ou une autre structure de données appropriée. S'ils sont dynamiques, vous souhaiterez peut-être renvoyer une sorte de structure de style de dictionnaire. Enfin, s'il y a des clés qui vont être constantes et un ensemble inconnu de clés dynamiques, vous souhaiterez peut-être renvoyer une structure de données hybride comprenant des valeurs fixes et une sorte de dictionnaire pour le débordement.

Wyatt Barnett
la source
En effet, votre conseil est correct, mais la question est de savoir ce qui ne va pas avec le choix d'utiliser la table de hachage lorsque la classe est un meilleur choix.
Muhammad Hasan Khan
Ce n'est ni l'un ni l'autre; une classe peut facilement contenir un dictionnaire si vous en avez besoin.
Wyatt Barnett