2009-09-22 5 views
5

Estoy escribiendo un método que forma parte de la interfaz pública de una clase de Java. En términos generales, permite al que llama especificar los valores que se asignarán a un número de entidades de base de datos, por lo que debe proporcionar tanto los ID de las entidades mismas como los valores que se les asignan.¿Es mejor usar una lista de pares o dos listas?

Estoy vacilando entre implementar esto como List<Pair<Integer, Integer>> o solo dos argumentos List<Integer>. Ambos obviamente trabajarían , y ninguno causaría ningún problema de implementación o eficiencia en mi método. Básicamente es la misma información en cualquier caso (una matriz 2xn), simplemente con rayas diferentes.

Así que me gustaría obtener algunas opiniones sobre cuál crees que sería mejor y por qué.

Ventajas que veo hasta ahora para la lista de pares:

  • refleja con mayor precisión la relación real entre las entidades
  • elimina algunas clases de error dinámico (por ejemplo, lista de longitudes unido mal)

Ventajas para el par de listas:

  • No confía en ningún n-JDK clases (simples como Pair es de entender como un concepto)
  • No requiere de la construcción de los objetos auxiliares sólo para transportar los datos en torno
  • Las personas que llaman son más propensos a tener los argumentos en listas separadas de todas formas, por lo no es necesario volver a alinear los datos antes de llamar al método

Ambos casos tienen la seguridad de tipo idéntico, así como la misma posibilidad de discrepancia de argumentos (por ejemplo, ingresando valores primero e IDs segundos cuando debería ser al revés). Este último problema se puede evitar creando un contenedor trivial alrededor de Integer llamado algo así como PrimaryKey, que tiene sus propios pros y contras y es ortogonal a este problema de todos modos, ya que se puede usar igual de bien en ambos casos.

Sin embargo, hay un término medio que podría ser una tercera opción: una clase de contenedor trivial con campos enteros para objectId y value. Esto no alista la ayuda del compilador para garantizar que los objetos sean correctos a través del tipado, pero proporciona una capa adicional de seguridad en las asignaciones. No creo que vaya por esto, sin embargo, ya que no me gusta la idea de contaminar una interfaz pública con una clase trivial como esta.

Respuesta

21

Deseo fuertemente recomiendo unir esos datos, posiblemente como un par, pero más como un contenedor específico. De esta forma, tiene la libertad de introducir funcionalidades adicionales relacionadas con esos dos objetos.

Mantener separadas las dos listas va a ser un problema. Tendrás que pasar los dos juntos y mantenerlos sincronizados. La sobrecarga de crear un nuevo objeto para esto es insignificante, y precisamente para qué está diseñado el OOP (creará clases que no sean JDK simplemente escribiendo un nuevo código Java para su aplicación, no lo olvide).

Creo clases menores como esta todo el tiempo. Imponen una seguridad de tipo fuerte y brindan la posibilidad de mejorar y refactorizar. Los IDE pueden identificar y realizar refactorizaciones más fácilmente.

+0

Todos los puntos buenos sobre el punto de OO, y las opciones de refactorización - gracias. –

+0

Como una ventaja adicional: si tiene una lista de pares, puede hacer una lista de triples fácilmente si lo necesita. Los requisitos cambian, ya sabes. –

+0

Por eso abogo por no utilizar un objeto Pair explícitamente :-) –

2

Cuando la API es pública, asegúrese de implementar la funcionalidad principal porque todo lo que le da a un cliente nunca se puede recuperar.

Piensa en un método con solo 2 parámetros asignar (Integer entityId, Integer someOtherId) y deja que el cliente descubra cómo agregar más elementos.

Si desea permitir un acceso conveniente, proporcione una clase util que viene con una interfaz "Asignación" que solo define getEntityId() y getSomeOtherId() y con una implementación predeterminada como DefaultAssignment que contiene referencias finales a los ids.

Luego, sus clientes pueden elegir qué camino desean y no deben asegurarse de respaldar su clase "Pair".

+0

Buen punto acerca de la interfaz, esto parece llegar a una conclusión similar a la respuesta de Brian Agnew. Objetos para todo! :-) –

+0

Exacta y buena suerte. – MrWhite

5

Creo que el análisis que ha realizado ya identifica muy bien los pros y los contras de los dos métodos.

También me inclinarse hacia el uso de la clase Pair, citando las ventajas que ha enumerado:

  • refleja con mayor precisión la relación real entre las entidades
  • elimina algunas clases de dinámica error (por ejemplo, longitudes de lista no coincidentes)

El más grande para mí sería el mejor.

Escriba siempre el código que demuestra la intención. No codifique pensando únicamente en la implementación.

El uso de una clase como Pair muestra la intención de que exista un par de valores que represente una ID y la propia entidad real. También muestra que un objeto Pair es una unidad discreta de datos que debe manejarse en conjunto, algo que no se puede deducir al tener dos List s separados de ID y entidades.

+0

+1 para la parte en negrita en particular: en la reflexión, tiene sentido que los clientes junten los argumentos en la forma en que mi método realmente los usa. –

0

En mi opinión, vaya con la lista de pares (o su propio contenedor más específico) ya que esto parece ser lo que refleja más naturalmente el problema que está resolviendo. Y es solo una variable para realizar un seguimiento de, y enviar a los métodos, en lugar de dos.

2

Iría por el List de Pair s, si los dos enteros realmente pertenecen juntos y se supone que representan "una cosa".

Otra desventaja de usar dos listas separadas es que el compilador no verifica si las listas son siempre del mismo tamaño. Y le deja la interpretación al cliente de su método; el cliente necesita hacer coincidir los elementos en las dos listas.

No veo usar una clase como Pair como una gran desventaja "porque depende de clases que no son JDK", como dices, pero si realmente no quieres usar algo como Pair, podrías incluso conviértalo en una lista de matrices: List<Integer[]>, donde cada matriz contiene los dos objetos Integer. (En mi opinión, eso es más feo que usar Pair).

5

¿Por qué no ir con un Dictionary (tipo de mapa, cualquiera que sea que Java lo llame hoy en día, creo que solía ser Hashtable)? Esto correlacionaría las ID con los valores y eludiría su dilema.

+0

+1 punto bueno - Me sorprende que no haya pensado en eso. Correctamente mapea la relación entre las dos cosas, así como cualquiera de las otras sugerencias. –

+0

un fondo de lenguaje de scripting podría ayudar. Hay un viejo adagio perl (yuck!): Si no estás pensando en hashes (diccionarios), no estás pensando en perl ... –

2

El enfoque de la lista de pares es lo más obvio que puede hacer, ya que refleja con mayor precisión la intención, pero un Mapa podría ser aún mejor si los ID son únicos.

Si tiene millones de estos pares, y el consumo de memoria se convierte en una importante consideración, es posible que desee cambiar a pares-de-listas (ya que habrá uno menos objeto por par).

0

Ir con la lista de pares o un mapa.

No estoy comprando ninguno de los argumentos "con" que enumeró.

Siempre debe pecar de mayor abstracción. Está escribiendo un lenguaje orientado a objetos, y la encapsulación y el ocultamiento de información son, en mi opinión, la razón más importante para pensar en los objetos. Oculta los detalles de implementación de los usuarios, permitiéndoles concentrarse en lo que ofrece su clase. Pueden olvidarse de cómo su clase logra lo que quieren. Obligar a sus clientes a mantener dos listas es pedirles que sepan más de lo que necesitan.

0

Escriba primero las pruebas unitarias. Luego puede ver fácilmente con qué es más fácil trabajar y luego elegirlo como su implementación.

+0

-1 esto puede ser cierto, pero no tiene nada que ver con la pregunta. – finnw

+0

Pregunta por opiniones qué es mejor. ¡El mejor es aquel con el que le gusta trabajar! –

0

Puede considerar hacer que el parámetro sea Iterator<Pair>. Si la clase de llamada tiene un List<Pair>, obtener el iterador es trivial. De lo contrario, crear el iterador podría ser más fácil de construir, más rápido y/o más natural. En algunos casos, incluso podría ayudarlo a eliminar problemas de falta de memoria.

1

que media en desacuerdo con este punto:

  • no se basa en ningún clases no JDK (simple como par es de entender como un concepto)

porque aunque no hay Pair clase en el JDK, hay una interfaz: Map.Entry que se ajusta a su uso previsto como una asociación clave/valor.

Cuestiones relacionadas