¿Existe una situación en la que sería mejor usar referencias débiles en lugar de una composición simple?

10

Aunque los documentos de Java especifican que las referencias débiles son principalmente para canonizar las asignaciones, encontrará muchas , muchas , muchas personas en Internet que afirman que WeakHashMap es perfecto para almacenar metadatos de objetos durante su vida útil. Sin embargo, nadie se molesta en hacer un ejemplo comprensible Y apropiado .

Usar WeakHashMap para agregar objetos algunas propiedades o almacenar sonidos de metadatos para mí, como una decisión arbitraria basada en la voluntad de usar la maldita cosa. En otras palabras, un mal diseño . Entiendo que hay situaciones en las que la herencia puede no estar disponible (clases finales, interfaces), pero ¿qué pasa con la composición? No puedo pensar en un ejemplo en el que la composición no sea una opción. Y sin duda uno mejor, porque se basa en un principio bien establecido, en lugar de una "peculiaridad del lenguaje".

Entonces, ¿hay una situación en la que sería mejor usar referencias débiles en lugar de una composición simple? Si no, ¿por qué todos en Internet parecen equivocarse?

Duende
fuente
Error lógico: "... decisión arbitraria basada en la voluntad de usar la maldita cosa. En otras palabras, un mal diseño". Los fines pueden no justificar los medios, pero los medios no son suficientes para controlar los fines. Dados los mismos métodos, el resultado podría ser hipotéticamente un buen diseño. Aunque para este caso no lo discutiría. :)
cwharris
3
Las referencias débiles son un concepto ortogonal de composición y herencia.
Robert Harvey

Respuestas:

13

Digamos que necesito asociar algunos metadatos con algunos objetos de datos. Este es un escenario bastante común. No controlo los objetos de datos, y hay muchos de ellos, y la API en cuestión (devoluciones de llamada, métodos virtuales, etc.) me ofrece esos objetos de datos, pero sin mis metadatos. Por lo tanto, necesito rastrear algún estado para cada uno de esos objetos de datos, es decir, los que he visto antes y podría volver a ver. Llamaré a estos metadatos un adorno, que es un término que a veces se usa para ese concepto.

La composición simple proporciona una búsqueda fácil del objeto de adorno (el que tiene metadatos) al otro objeto (el que tiene datos), con la presunción de que, dado que controlo el diseño del objeto de metadatos, puedo poner una referencia directamente al objeto de datos .

Sin embargo, a menos que controle el diseño del objeto de datos y pueda cambiarlo, la composición simple no proporciona la búsqueda inversa (del objeto de datos a algunos metadatos). De hecho, a menos que tenga una colección de objetos de metadatos, ni siquiera puede ubicar el elemento de metadatos asociado dado un elemento de objeto (datos).

Además del problema de buscar en la dirección que va desde el objeto para encontrar sus metadatos de adorno, también existe el problema de la vida útil de los metadatos.

Los metadatos que se acumulan y nunca se liberan incluso cuando el objeto de datos ya no se usa es una pérdida de memoria.

Un hashmap de referencia débil resuelve ambos problemas. Permite localizar los metadatos dados los datos, y permite que los metadatos se liberen en algún momento después de que se liberan los datos.

Tenga en cuenta además que un hashmap de referencia débil permite no solo recuperar (metadatos) valores (gc'ed), sino también las claves (datos) a reclamar (gc'ed), ya que si las claves se mantuvieran, eso también sería un pérdida de memoria y, además, los valores nunca podrían ser liberados tampoco.

Erik Eidt
fuente
¿Por qué el uso de los objetos de datos con una tabla de metadatos respaldada por hashmap débil no cuenta como composición?
Jack
2
@Jack, Composición, especialmente "composición simple" en mi mente al menos, son objetos que se refieren a otros objetos, pero directamente. La relación de composición "tiene-a" se expresa usando una referencia simple, o algunas veces una colección. Aquí el hashmap es un método indirecto. No puede alcanzar el adorno si no tiene el hashmap. Mientras que en composición puedes hacer esta navegación. Por lo tanto, prefiero llamar a estos metadatos un adorno en lugar de una composición, pero ciertamente están relacionados. FWIW, el adorno se compone (en mi humilde opinión) con los datos, pero no al revés.
Erik Eidt
@Jack, re: mi último FWIW, me di cuenta de que al usar el hashmap débil normalmente no pondrías una referencia del objeto de adorno de metadatos al otro debido a la retención de memoria (o si quisieras el has-a en ese dirección, tendría que ser una referencia débil). Por lo tanto, normalmente el cliente de hashmap débil funciona con dos objetos que están efectivamente emparejados entre sí pero que técnicamente no están en la composición de objetos entre sí.
Erik Eidt