Si tengo una variable que contiene un List
, podría contener objetos de muchos tipos diferentes, por ejemplo, ArrayList
o LinkedList
. La diferencia entre a LinkedList
y an ArrayList
es bastante grande. El gran comportamiento O de los métodos difiere mucho. Por ejemplo, ordenar el List
y luego usarlo para hacer búsquedas binarias está perfectamente bien para un ArrayList
pero no tendría sentido con un LinkedList
.
java
object-oriented-design
Estacada
fuente
fuente
Respuestas:
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
List
sin 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
.fuente
Iterable
.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
List
no 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:
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.
fuente
equals
para comparar objetos.LinearSpace
yLogarithmicTime
y luego declarar clases comopublic class BinarySearch : ISearchStrategy<T>, LogarithmicTime
. Otras clases podrían tomar parámetros comopublic T find<T, S>(IList<T> list, S strategy) where S : ISearchStrategy<T>, LogarithmicTime { }
imponer restricciones de rendimiento.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
RandomAccess
lugar deList
. Si no siente la necesidad de hacer ese cambio (y pocos lo hacen), entonces quizás List no tenga tanta fuga.fuente
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,
ArrayList
modela 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 .fuente