¿Qué hay de malo en devolver la tabla hash del método público y cuándo tiene sentido hacerlo?

9

¿Cuáles son los problemas de diseño al devolver una tabla hash de un método público cuando desea devolver varios elementos en lugar de crear una clase y devolver un objeto de eso?

Si tiene problemas, ¿en qué circunstancias tiene sentido hacerlo?

¿Cómo cambia la respuesta a esta pregunta dependiendo de si el lenguaje es dinámico o no?

Editar: Esto es para aclarar que las claves serían constantes y son parte del código, no de los datos. Algo para lo que generalmente creamos una clase. La pregunta es por qué sería un error usar hashtable en su lugar si crear una clase realmente parece ser la opción correcta.

Muhammad Hasan Khan
fuente

Respuestas:

11

Utilice una clase mejor definida como tipo de retorno que una tabla hash que contenga un número arbitrario de valores como pares de nombre / valor.

  1. El primer y más importante punto es - Mantenimiento. Al mirar el código, un nuevo programador nunca puede decir cuáles son los valores que está devolviendo el método. Si una nueva persona no entiende esto al mirar el código, el código no será útil y propenso a errores cada vez que alguien agregue más claves / valores a esos datos o mejore la aplicación.

  2. Los métodos son contratos entre la persona que llama y el servicio. Lo más importante en un método es su entrada y salida. Esta entrada y salida debe ser fácilmente legible, comprensible y auto documentada. Si usa una clase Persona como valor de retorno que tiene nombre, apellido, edad, se documenta por sí mismo. Si genera un Javadoc para esto, el usuario puede navegar entre las clases para comprenderlo mejor. Si usa una tabla hash, debe explicarla en los comentarios que nadie leerá o actualizará cuando las cosas cambien.

  3. No puede usar genéricos como HashMap<String,String>en el caso si desea agregar un número (por ejemplo, edad) a la declaración de devolución. Si no usa genéricos, tendrá que lanzar de un lado a otro entre el objeto al tipo real. Puede guardar esto si usa la escritura dinámica.

  4. También hay más posibilidades de fallas en tiempo de ejecución que problemas de captura en tiempo de compilación. por ejemplo, si alguien elimina una entrada del hashmap y uno de los antiguos llamantes espera la entrada, el cliente falla durante el tiempo de ejecución. Siempre es mejor detectar este problema en tiempo de compilación.

  5. Será difícil devolver un tipo inmutable si desea utilizar hashmap como tipo de retorno, etc. Pero si usa un usuario que definió su propio tipo, puede controlar esto.

Será tentador usar un hashmap como tipo de retorno porque puede evitar crear un par de clases al principio, pero será una pesadilla mantener el código en el futuro. Ir orientado a objetos !!!!

java_mouse
fuente
1
Parece que has entendido la pregunta correctamente. Gracias.
Muhammad Hasan Khan
8

Uno de los problemas sería que, en muchos casos, la clave para la tabla hash sería una cadena. Por lo tanto, los consumidores del método tendrían que saber de antemano qué teclas utilizar para extraer los datos. Esto daría la posibilidad de errores debido a errores ortográficos al acceder a los datos.

Otro inconveniente es la refactorabilidad. Si luego decides cambiar el nombre de un miembro, entonces tienes un montón de cadenas mágicas que también necesitan cambiar. Es mucho más simple cambiar el nombre de un miembro de la clase utilizando las herramientas de refactorización proporcionadas por la mayoría de los buenos IDE. Con una tabla hash, es probable que tenga que hacer una operación de búsqueda / reemplazo en todos los archivos de origen, lo que podría ser problemático.

Por último, perderá tiempo de compilación comprobando el acceso de los miembros, tanto en términos de nombre como de tipo. Este último no es un problema si su tabla hash solo contiene un tipo de objeto, pero si contiene muchos (incluso en la misma cadena jerárquica) realmente desea aprovechar el sistema de tipos de su idioma y obtener tiempo de compilación comprobando allí. En la mayoría de los IDE, tendrá algún tipo de funciones intellisense / autocompletar: funcionan al observar el sistema de tipos, pero no podrán ayudarlo con las teclas de tabla hash.

En cuanto a los momentos en que sería apropiado devolver una tabla hash (u otra colección de pares de valores de clave), lo usaría cuando no se conocen los valores y las claves en el momento de la compilación. Por ejemplo, si tiene un método que analiza una cadena de consulta y devuelve las claves y los valores correspondientes, una tabla hash sería una buena opción. En este caso, también querrás pensar en devolver algún tipo de tabla hash inmutable o de solo lectura.

Editar : la mayoría de los puntos planteados en esta respuesta dejan de aplicarse cuando se habla de lenguajes dinámicos :)

MattDavey
fuente
¿Qué pasa si el lenguaje es dinámico?
Muhammad Hasan Khan
No soy un experto en lenguajes dinámicos, por lo que otra persona probablemente pueda proporcionar una mejor respuesta para eso. Pero sí sé que los lenguajes dinámicos no comprueban el tipo de tiempo de compilación de todos modos. Pero en ese caso, devolver un objeto y devolver una tabla hash no es tan diferente ...
MattDavey
3
@Hasan Khan: en ese caso, en realidad puede no haber ninguna diferencia entre una tabla hash y una instancia de clase. Por ejemplo, en Javascript todos los objetos son tablas hash, y object.property es exactamente lo mismo que objeto ['propiedad']
Michael Borgwardt
"Con una tabla hash, es probable que tenga que hacer una operación de buscar / reemplazar en todos los archivos de origen, lo que podría ser problemático". Solo si ha elegido claves pobres y nunca ha tratado de descifrar las claves estándar para que se definan en un solo lugar ...
Donal Fellows
7

El argumento más importante en contra de esto sería que está exponiendo demasiada información al consumidor. El código consumidor solo necesita saber que es una colección de valores clave (diccionario) de algún tipo; si se implementa como un hashmap, una lista de asociación, un trie o lo que sea, es relativamente poco interesante. Por lo tanto, la forma correcta sería regresar por una interfaz adecuada ( IDictionaryo cualquier idioma que elija) en lugar de por tipo real.

Todo esto suponiendo que realmente necesita un diccionario para representar sus datos, es decir, sus datos consisten en pares clave / valor, donde las claves son únicas entre el conjunto de datos y no pueden repararse en el momento de la compilación. Si tiene claves previamente conocidas, debe crear un tipo adecuado (o varios, según sea necesario) para sus datos. Se trata de si considera las claves en sí mismas como parte de los datos o como parte del código.

EDITAR :

Para aclarar, estoy usando el término diccionario para referirse al tipo más genérico de estructura de datos clave-valor aquí; No me refiero a ninguna implementación específica del idioma, como Python dicto .NET Dictionary.

tdammers
fuente
1
+1 para "Se trata de si considera las claves en sí mismas como parte de los datos o como parte del código". - Esa es una buena manera de decirlo. No estoy seguro de cuán universal es el término "diccionario" en comparación con "mapa", por ejemplo.
MattDavey
Devolver el diccionario no fue intencionado. Las claves eran parte del código, no de los datos.
Muhammad Hasan Khan
La verdadera pregunta es el razonamiento detrás de 'Deberías estar creando un tipo apropiado'. La pregunta es por qué?
Muhammad Hasan Khan
2

Una pregunta que me haría es "¿están cambiando las claves en este diccionario?" Si son constantes, debe devolver un objeto u otra estructura de datos adecuada. Si son dinámicos, es posible que desee devolver algún tipo de estructura de estilo de diccionario. Finalmente, si hay algunas claves que van a ser constantes y algún conjunto desconocido de claves dinámicas, es posible que desee devolver una estructura de datos híbrida que incluya algunos valores fijos y algún tipo de diccionario para el desbordamiento.

Wyatt Barnett
fuente
De hecho, su consejo es correcto, pero la pregunta es qué hay de malo en elegir la tabla hash cuando la clase es una mejor opción.
Muhammad Hasan Khan
No es ni / ni; una clase puede contener fácilmente un diccionario si lo necesita.
Wyatt Barnett