¿Es la interfaz de la lista una abstracción con fugas?

9

Si tengo una variable que contiene un List, podría contener objetos de muchos tipos diferentes, por ejemplo, ArrayListo LinkedList. La diferencia entre a LinkedListy an ArrayListes bastante grande. El gran comportamiento O de los métodos difiere mucho. Por ejemplo, ordenar el Listy luego usarlo para hacer búsquedas binarias está perfectamente bien para un ArrayListpero no tendría sentido con un LinkedList.

Estacada
fuente
¿Qué significa "la gran O"?
Tulains Córdova
@ user61852 en.wikipedia.org/wiki/Big_O_notation
Paling el

Respuestas:

25

Yo no diría eso.

Una abstracción con fugas es aquella que te obliga a lidiar con los detalles de implementación que se supone que deben abstraerse. Pero el rendimiento siempre difiere entre las implementaciones, por lo que si cuenta eso como una fuga, entonces no hay abstracciones sin fugas.

Si se declara algo Listsin más documentación, debe entenderse que simplemente no hay garantías sobre el rendimiento, y si va a hacer algo sensible al rendimiento, debe hacer una copia y trabajar con eso.

Además, no se olvide que hay una interfaz aún más general que es a menudo suficiente en la funcionalidad y no tienta a hacer tantas suposiciones sobre el rendimiento: Collection.

Michael Borgwardt
fuente
99
Existe una interfaz aún más general, que es a menudo suficiente en la funcionalidad: Iterable.
emory
Se esperan diferencias de rendimiento entre las diferentes implementaciones. Por ejemplo, existen diferencias entre Vector y ArrayList, pero una operación get en una LinkedList parece extraña.
Paling
17

Todas las abstracciones no triviales, hasta cierto punto, tienen fugas. Dicho esto, no estoy realmente seguro de que se aplique aquí. :-)

Las abstracciones tienen que ver con el comportamiento. A menos que el comportamiento especifique un rendimiento particular (que Java Listno lo hace) es un detalle de implementación, es decir, irrelevante.

Java no le permite especificar un rendimiento mínimo para las interfaces fuera de la documentación, y no conozco ningún lenguaje que lo haga; sería increíblemente difícil (¿imposible?) Que el compilador lo verifique. Puedo ver un par de opciones si el rendimiento es una preocupación:

  1. Documente en la clase / interfaz a la que pertenecerá la instancia de la lista.
  2. Cree una nueva interfaz, por ejemplo BinarySearchPerformantList(¡qué asco!), Que especifica los requisitos de rendimiento de los distintos métodos.

La opción 2 es probablemente la mejor abstracción, pero viene con una sobrecarga adicional.

vaughandroid
fuente
1
+1. Técnicamente sí, una Lista es una abstracción permeable , pero también lo es el Objeto para ocultar la complejidad relacionada con el uso equalspara comparar objetos.
Neil
2
@Neil, creo que es discutible ... Dado que la abstracción no menciona el rendimiento, no creo que esté fallando en este caso (como he argumentado). Diría que si está pensando en el rendimiento, necesita una abstracción diferente / más estrecha. Se editará para mencionar eso.
vaughandroid
Depende de lo que estés escondiendo, supongo. ¿Es la complejidad en el uso o en el uso y la implementación de su memoria? Porque si se trata de una clase abstracta, una o más de estas complejidades se ocultan de una forma u otra.
Neil
He jugado un poco muchos años atrás la implementación de una variación de la opción 2 mediante interfaces de marcador como LinearSpacey LogarithmicTimey luego declarar clases como public class BinarySearch : ISearchStrategy<T>, LogarithmicTime. Otras clases podrían tomar parámetros como public T find<T, S>(IList<T> list, S strategy) where S : ISearchStrategy<T>, LogarithmicTime { }imponer restricciones de rendimiento.
Lucas
2
Si vamos por el artículo de Joel Spolsky, creo que es "hasta cierto punto, permeable". Consulte la siguiente cita del artículo: "Si fue brusco con los administradores del sistema de su empresa y lo castigaron conectándolo a un concentrador sobrecargado, solo pasarán algunos de sus paquetes IP y TCP funcionará, pero todo funcionará sea ​​realmente lento "Creo que esto se aplica
Programador Amish
4

En Java, hay una interfaz RandomAccess que se define como una lista con un tiempo de acceso aleatorio generalmente constante (O (1) get, put, etc.). Si cree que su módulo requiere una lista con esas características de rendimiento, considere usar en RandomAccesslugar de List. Si no siente la necesidad de hacer ese cambio (y pocos lo hacen), entonces quizás List no tenga tanta fuga.

MikeFHay
fuente
1

Tienes razón, una Lista es una abstracción permeable. El STL utiliza la idea de conceptos para modelar este problema específico. Para usar su ejemplo, ArrayListmodela un iterador de acceso aleatorio mientras que LinkedList modela un iterador de reenvío . Los diferentes conceptos tienen diferentes requisitos de rendimiento, lo que los hace apropiados para diferentes algoritmos .

Matthew Finlay
fuente