¿Por qué se implementaron las colecciones Java con "métodos opcionales" en la interfaz?

69

Durante mi primera implementación que extendió el marco de la colección Java, me sorprendió bastante ver que la interfaz de la colección contiene métodos declarados como opcionales. Se espera que el implementador lance UnsupportedOperationExceptions si no es compatible. Esto inmediatamente me pareció una mala elección de diseño de API.

Después de leer gran parte del excelente libro "Eficaz Java" de Joshua Bloch, y luego de enterarse de que él puede ser responsable de estas decisiones, no parece estar de acuerdo con los principios expuestos en el libro. Creo que declarar dos interfaces: Collection y MutableCollection, que amplía Collection con los métodos "opcionales", habría dado lugar a un código de cliente mucho más mantenible.

Hay un excelente resumen de los problemas aquí .

¿Hubo una buena razón por la que se eligieron métodos opcionales en lugar de la implementación de las dos interfaces?

    
pregunta glenviewjeff 20.05.2011 - 16:18

4 respuestas

28

La Preguntas frecuentes proporciona la respuesta. En resumen, vieron una potencial explosión combinatoria de las interfaces necesarias con vista modificable, no modificable, solo eliminar, solo agregar, longitud fija, inmutable (para subprocesos), etc. para cada conjunto posible de métodos de opción implementados.

    
respondido por el ratchet freak 20.05.2011 - 17:09
10

Me parece que el Interface Segregation Principle no se exploró tan bien como ahora; esa forma de hacer las cosas (es decir, su interfaz incluye todas las operaciones posibles y tiene métodos "degenerados" que generan excepciones para las que no necesita) fue popular antes de que SOLID e ISP se convirtieran en el estándar de facto para el código de calidad.

    
respondido por el Wayne Molina 20.05.2011 - 17:20
4

Si bien algunas personas pueden odiar los "métodos opcionales", en muchos casos pueden ofrecer una mejor semántica que las interfaces altamente segregadas. Entre otras cosas, permiten las posibilidades de que un objeto gane habilidades o características en su vida útil, o que un objeto (especialmente un objeto envoltorio) no sepa cuándo se construye qué habilidades exactas debe informar.

Aunque difícilmente llamaré a las clases de colecciones Java un buen diseño, sugeriría que un buen marco de colecciones debería incluir en su base una gran cantidad de métodos opcionales junto con formas de preguntar a una colección sobre sus características y habilidades . Un diseño de este tipo permitirá que se utilice una única clase de envoltura con una gran variedad de colecciones sin que se oculten accidentalmente las capacidades que la colección subyacente pueda tener. Si los métodos no fueran opcionales, entonces sería necesario tener una clase de envoltorio diferente para cada combinación de características que las colecciones puedan admitir, o de lo contrario, algunos envoltorios serán inutilizables en algunas situaciones.

Por ejemplo, si una colección admite la escritura de un elemento por índice o la adición de elementos al final, pero no admite la inserción de elementos en el medio, entonces el código que desee encapsularlo en un contenedor que registraría todas las acciones realizadas en él Necesitará una versión de la envoltura de registro que proporcione la combinación exacta de habilidades admitidas, o si no hubiera ninguna disponible, tendría que usar una envoltura que admitiera la adición o escritura por índice, pero no ambas. Sin embargo, si una interfaz de colección unificada proporcionaba los tres métodos como "opcionales", pero luego incluía métodos para indicar cuál de los métodos opcionales sería utilizable, entonces una sola clase envoltura podría manejar colecciones que implementan cualquier combinación de características. Cuando se le pregunta qué funciones admite, un contenedor podría simplemente informar lo que sea que admita la colección encapsulada.

Tenga en cuenta que la existencia de "habilidades opcionales" puede en algunos casos permitir que las colecciones agregadas implementen ciertas funciones de maneras mucho más eficientes de lo que serían posibles si las capacidades estuvieran definidas por la existencia de implementaciones. Por ejemplo, supongamos que se utilizó un método concatenate para formar una colección compuesta de otros dos, el primero de los cuales fue un ArrayList con 1,000,000 elementos y el último de los cuales fue una colección de veinte elementos que solo podría ser iterado desde el comienzo. Si a la colección compuesta se le pidiera el elemento 1,000,013 (índice 1,000,012), podría preguntar a la ArrayList cuántos elementos contenía (es decir, 1,000,000), restar eso del índice solicitado (que produce 12), leer y omitir doce elementos del segundo colección, y luego devolver el siguiente elemento.

En tal situación, aunque la colección compuesta no tendría una forma instantánea de devolver un artículo por índice, pedir la colección compuesta para el artículo 1,000,013 sería aún más rápido que leer 1,000,013 artículos individualmente e ignorar todos pero el último.

    
respondido por el supercat 04.10.2014 - 23:10
-1

Lo atribuiría a los desarrolladores originales, pero no lo sabían mejor en ese entonces. Hemos avanzado mucho en diseño de OO desde 1998 aproximadamente cuando se lanzaron Java 2 y Colecciones por primera vez. Lo que parece obvio mal diseño ahora no era tan obvio en los primeros días de la POO.

Pero se pudo haber hecho para evitar lanzamientos extra. Si fuera una segunda interfaz, tendrías que convertir tus instancias de colecciones para llamar a esos métodos opcionales, lo que también es un poco feo. Tal como está ahora, puede capturar una excepción de excepción no admitida de inmediato y corregir su código. Pero si hubiera dos interfaces, tendrías que usar instanceof y casting por todas partes. Quizás lo consideraron una compensación válida. También en los primeros días de Java, 2 días, instanceof estaba muy mal visto debido a su bajo rendimiento, ya que podrían haber estado tratando de evitar el uso excesivo.

Por supuesto, esto es toda una especulación salvaje, dudo que alguna vez podamos contestar esto con seguridad a menos que uno de los arquitectos de colecciones originales intervenga.

    
respondido por el Jberg 20.05.2011 - 16:40

Lea otras preguntas en las etiquetas