Czy jest sytuacja, w której lepiej byłoby użyć słabych referencji zamiast prostej kompozycji?

10

Chociaż docs Java określić, że odniesienia Słabe są przede wszystkim dla canonicalizing mapowania, znajdziesz wiele , wiele , wiele ludzi w internecie stwierdzające, że WeakHashMap jest idealny do przechowywania metadanych obiektu w trakcie jego trwania. Jednak nikt nie zadaje sobie trudu, aby podać zrozumiały I odpowiedni przykład.

Używanie WeakHashMap do dodawania do obiektu niektórych właściwości lub przechowywania dźwięków metadanych, jak arbitralna decyzja oparta na chęci użycia tego cholerstwa. Innymi słowy - zły projekt . Rozumiem, że są sytuacje, w których dziedziczenie może nie być dostępne (klasy końcowe, interfejsy), ale co ze składem? Nie mogę wymyślić jednego przykładu, w którym kompozycja nie byłaby opcją. I na pewno lepszy, ponieważ opiera się na ugruntowanej zasadzie, zamiast „dziwactwa językowego”.

Czy jest więc sytuacja, w której lepiej byłoby użyć słabych referencji zamiast prostej kompozycji? Jeśli nie, to dlaczego wszyscy w Internecie źle to rozumieją?

Krasnoludek
źródło
Błąd logiczny: „... arbitralna decyzja oparta na chęci użycia tego cholerstwa. Innymi słowy - zły projekt”. Cele mogą nie uzasadniać środków, ale środki nie są wystarczające, aby kontrowersować cele. Przy tych samych metodach wynik może być hipotetycznie dobrym projektem. Chociaż w tej sprawie nie będę tego argumentować. :)
cwharris
3
Słabe odniesienia to ortogonalna koncepcja składu i dziedziczenia.
Robert Harvey

Odpowiedzi:

13

Powiedzmy, że muszę skojarzyć niektóre metadane z niektórymi obiektami danych. To dość powszechny scenariusz. Nie kontroluję obiektów danych, a jest ich wiele, a interfejs API (wywołania zwrotne, metody wirtualne itp.) Oferuje mi te obiekty danych, ale bez moich metadanych. Muszę więc śledzić stan każdego z tych obiektów danych, mianowicie te, które widziałem wcześniej i które mogę zobaczyć ponownie. Nazwę te metadane ozdobą, która jest czasem używana w odniesieniu do tego pojęcia.

Prosta kompozycja umożliwia łatwe wyszukiwanie od obiektu ozdobnego (tego z metadanymi) do drugiego obiektu (tego z danymi), przy założeniu, że skoro kontroluję projekt obiektu metadanych, mogę umieścić w nim odniesienie bezpośrednio do obiektu danych .

Jednak jeśli nie kontrolujesz projektu obiektu danych i nie możesz go zmienić, prosta kompozycja nie zapewnia wyszukiwania wstecznego (od obiektu danych do niektórych metadanych). W rzeczywistości, chyba że masz kolekcję obiektów metadanych, nie możesz nawet zlokalizować powiązanego elementu metadanych, biorąc pod uwagę element obiektu (danych).

Oprócz problemu wyszukiwania w kierunku od obiektu, aby znaleźć jego ozdobne metadane, istnieje również problem trwałości metadanych.

Metadane, które gromadzą się i nigdy nie są uwalniane, nawet gdy obiekt danych nie jest już używany, stanowią wyciek pamięci.

Słaba mapa odniesienia rozwiązuje oba problemy. Pozwala zlokalizować metadane na podstawie danych i umożliwia uwolnienie metadanych w pewnym momencie po uwolnieniu danych.

Zauważ też, że słaby skrót odwołujący się pozwala nie tylko odzyskać (metadane) wartości (gc'ed), ale także klucze (danych) do odzyskania (gc'ed), ponieważ jeśli klucze byłyby przechowywane, byłoby to również wyciek pamięci, a ponadto wartości nie mogły zostać nigdy zwolnione.

Erik Eidt
źródło
Dlaczego używanie obiektów danych z tabelą metadanych opartą na słabym haszowaniu nie jest liczone jako kompozycja?
Jack
2
@Jack, Kompozycja, a zwłaszcza „prosta kompozycja”, moim zdaniem, to obiekty odnoszące się do innych obiektów, ale bezpośrednio tak. Zależność składu „ma-a” wyraża się za pomocą prostego odniesienia, a czasem kolekcji. Tutaj skrót mapy jest metodą pośrednią. Nie możesz dotrzeć do ozdoby, jeśli nie masz mapy. Podczas gdy w składzie można wykonać tę nawigację. Dlatego wolę nazywać te metadane bardziej ozdobą niż kompozycją, ale z pewnością są one powiązane. FWIW, ozdoby (IMHO) komponują się z danymi, ale nie na odwrót.
Erik Eidt
@Jack, re: mój ostatni FWIW, właśnie zdałem sobie sprawę, że podczas korzystania ze słabego haszapa normalnie nie umieściłbyś odniesienia z obiektu ozdabiającego metadane do drugiego z powodu wstrzymania pamięci (lub jeśli chciałbyś mieć has-a w tym kierunek, musiałby to być słaby punkt odniesienia). Tak więc zazwyczaj słaby klient mapowania działa z dwoma obiektami, które są skutecznie sparowane ze sobą, ale technicznie nie są ze sobą w składzie obiektów.
Erik Eidt