Есть ли ситуация, когда было бы лучше использовать слабые ссылки вместо простой композиции?

10

Хотя в документах Java указано, что слабые ссылки предназначены главным образом для канонизации отображений, вы обнаружите, что многие , многие , многие люди в Интернете заявляют, что WeakHashMap идеально подходит для хранения метаданных объекта в течение его срока службы. Тем не менее, никто не мешает сделать понятный и соответствующий пример.

Использование WeakHashMap, чтобы добавить объекту некоторые свойства или сохранить звуки метаданных для меня, как произвольное решение, основанное на желании просто использовать эту чертову вещь. Другими словами - плохой дизайн . Я понимаю, что существуют ситуации, когда наследование может быть недоступно (конечные классы, интерфейсы), но как насчет композиции? Я не могу вспомнить ни одного примера, где композиция не была бы вариантом. И, конечно, лучше, потому что он основан на устоявшемся принципе, а не на "языковой причуде".

Итак, есть ли ситуация, когда было бы лучше использовать слабые ссылки вместо простой композиции? Если нет, то почему все в Интернете, кажется, ошибаются?

гном
источник
Логическая ошибка: «... произвольное решение, основанное на желании просто использовать эту чертову штуку. Другими словами - плохой дизайн». Цели могут не оправдывать средства, но средств недостаточно, чтобы опровергнуть цели. Учитывая те же методы, результат может быть гипотетически хорошим дизайном. Хотя для этого случая я бы не стал спорить. :)
cwharris
3
Слабые ссылки - это ортогональное понятие к составу и наследованию.
Роберт Харви

Ответы:

13

Допустим, мне нужно связать некоторые метаданные с некоторыми объектами данных. Это довольно распространенный сценарий. Я не контролирую объекты данных, и их много, и рассматриваемый API (обратные вызовы, виртуальные методы и т. Д.) Предлагает мне эти объекты данных, но без моих метаданных. Итак, мне нужно отследить некоторое состояние для каждого из этих объектов данных, а именно тех, которые я видел раньше и мог бы увидеть снова. Я назову эти метаданные украшением, которое иногда используют для этой концепции.

Простая композиция обеспечивает легкий поиск от украшающего объекта (объекта с метаданными) до другого объекта (объекта с данными), исходя из предположения, что, поскольку я контролирую дизайн объекта метаданных, я могу поместить в него ссылку непосредственно на объект данных. ,

Однако, если вы не управляете дизайном объекта данных и не можете его изменить, простая композиция не обеспечивает обратного просмотра (от объекта данных до некоторых метаданных). Фактически, если у вас нет коллекции объектов метаданных, вы даже не можете найти связанный элемент метаданных с данным объектом (данными).

В дополнение к проблеме поиска в направлении, идущем от объекта, чтобы найти его украшающие метаданные, существует также проблема времени жизни метаданных.

Метаданные, которые накапливаются и никогда не высвобождаются, даже если объект данных больше не используется, являются утечкой памяти.

Хэш-карта со слабой ссылкой решает обе проблемы. Это позволяет найти метаданные для данных и позволяет освободить метаданные через некоторое время после освобождения данных.

Отметим далее, что хэш-карта со слабой ссылкой позволяет не только (метаданные) значения восстанавливать (gc'ed), но и (data) ключи восстанавливать (gc'ed), поскольку, если бы ключи были сохранены, это также было бы утечка памяти, и, кроме того, значения никогда не могут быть освобождены либо.

Эрик Эйдт
источник
Почему не используются объекты данных со слабой таблицей метаданных на основе hashmap в качестве композиции?
Джек,
2
@ Джек, Композиция, особенно «простая композиция», по крайней мере, на мой взгляд, это объекты, относящиеся к другим объектам, но прямо так. Отношение «имеет-а» композиции выражается с использованием простой ссылки или иногда коллекции. Здесь hashmap является косвенным методом. Вы не можете достичь украшения, если у вас нет хэш-карты. Тогда как в составе вы можете сделать эту навигацию. Поэтому я предпочитаю называть эти метаданные украшением, а не композицией, но они, безусловно, связаны между собой. FWIW, украшения (IMHO) сочетаются с данными, просто не наоборот.
Эрик Эйдт
@Jack, re: мой последний FWIW, я только что понял, что при использовании слабого hashmap вы обычно не помещаете ссылку из объекта, украшающего метаданные, в другой из-за удержания памяти (или если вы хотите, чтобы has-a в этом направление, это должно было бы быть слабой ссылкой). Таким образом, обычно слабый клиент hashmap работает с двумя объектами, которые эффективно связаны друг с другом, но технически не находятся в композиции объектов друг с другом.
Эрик Эйдт