2010-05-30 12 views
11

dlaczego wykazy słuchacza (np Java te, które wykorzystują addXxxListener() i removeXxxListener() się zarejestrować i wyrejestrować słuchaczy) o nazwie listy i zwykle realizowane jako Lists? Nie Set być lepsze dopasowanie, ponieważ w przypadku słuchaczy nieDlaczego listy słuchaczy są listami?

  • Bez względu na to, w jakiej kolejności dostają nazwie (chociaż mogą być również takie potrzeby, ale są przypadki szczególne; zwykłe mechanizmy słuchaczy zrobić bez takich gwarancji) oraz
  • Nie ma potrzeby, aby zarejestrować ten sam słuchacza więcej niż jeden raz (czy robi to powinno spowodować wywołanie tego samego słuchaczowi 1 razy lub n razy, lub być błąd, to inna kwestia)

Czy to tylko kwestia tradycji? Zestawy to i tak jakieś listy pod maską. Czy są różnice w wydajności? Czy iteracja poprzez List jest szybsza czy wolniejsza niż iterowanie przez Set? Czy zajmuje mniej lub więcej pamięci? Różnice są z pewnością prawie nieistotne.

+10

bo to jest listener? : p – kennytm

Odpowiedz

8

Jednym z ważnych powodów, dla których listy słuchaczy są listami (zamiast zestawów), jest również wyjaśnienie, dlaczego często widzisz, że są one iterowane wstecz. Typowy scenariusz obejmuje słuchacza, który usuwa się jako słuchacz, gdy jest powiadamiany o pewnych zmianach. Jeśli detektory były przechowywane jako lista i iterowane do przodu (lub przechowywane jako zestaw i iterowane w nieokreślonej kolejności), usunięcie siebie jako detektora spowoduje wyjątek ConcurrentModificationException.

Zamiast tego słuchacze są zapisywani jako lista i powiadamiani w odwrotnej kolejności. Następnie, jeśli detektor usuwa się z listy obiektów nasłuchiwania, gdy jest powiadamiany, nie powoduje to wyjątku ConcurrentModificationException ani nie przesuwa indeksów innych nie-jeszcze-zgłoszonych odbiorców.

+0

Co jeśli nie dbasz o zamówienie? –

+0

Jeśli twoi słuchacze kiedykolwiek usuwają się w odpowiedzi na powiadomienia, powinieneś się tym przejmować. W przeciwnym razie nic nie straciłeś, zachowując zamówienie. – Mark

+0

jeśli się usuwają, dlaczego mam się tym przejmować? Myślę, że w większości przypadków dobrze jest użyć zestawu. słuchacze zwykle nie powinni zakładać, kiedy będą nazywać się w porównaniu do innych słuchaczy. Może SkipList jest rozwiązaniem tego w środku? dziwne, nie mogę znaleźć dla niego klasy Java. –

1

Jaki zestaw? Czy wszyscy nasi odbiorcy powinni zaimplementować equals i hashCode, aby użyć zestawu mieszającego, czy też zestaw mieszania tożsamości? Czy przypadkiem jest dodanie słuchacza do listy dwukrotnie wartej złożoności? Czy istnieje prosty mechanizm zabezpieczający zestaw przed dodawaniem lub usuwaniem odbiorców podczas połączeń z ich programami?

Możliwe, że występują pewne różnice w wydajności, ale na pewno są bardziej skomplikowane projekty, co zmusza wiele decyzji o usunięciu wielu dodatków do biblioteki, zamiast pozostawiać ją w aplikacji.

+0

Myślę, że zestaw wartości mieszającej tożsamości byłby odpowiedni. Ale przyznane, nie ma "CopyOnWriteIdentityHashSet" dostępnego po wyjęciu z pudełka, więc używanie wspólnego idiomu listy może być prostsze w osiąganiu poprawnego wyniku końcowego. –

+0

Ale: rzeczywiście istnieje CopyOnWriteArraySet w Javie 6, który jest bezpieczny dla wątków ("Traversal przez iteratory jest szybki i nie może napotkać interferencji z innych wątków."). Według http://java.sun.com/javase/6/docs/technotes/guides/collections/changes5.html "Ta implementacja dobrze nadaje się do zarządzania listami zdarzeń, które muszą zapobiegać duplikatom." –

+1

@Joonas Ponieważ procedury obsługi Swing są wywoływane w wątku Swing, problemem zawsze była modyfikacja podstawowej kolekcji i unieważnianie iteratora zamiast współbieżnych aktualizacji. Ale jeśli chcesz tych semantyków, z pewnością możesz użyć zestawu do kopiowania na piśmie. –

0

Masz całkowitą rację. Słuchacze powinni zostać dodani do zestawów. Jak już powiedziałeś, dodawanie słuchacza więcej niż raz nie ma sensu. Ponadto nie można polegać na kolejności słuchaczy, jeśli używasz zestawów. I to jest najważniejsze: NIE POWINIENEM polegać na tym, jeśli podejmiesz poważny rozwój oprogramowania i każda zasada, którą odkryliśmy, doprowadzi nas do lepszego projektowania: izolacja, niezależność, odpowiedzialność.

Każdy aspekt tutaj wymieniony (wielowątkowość, wydajność, ...) musi podporządkować się w pierwszej myśli, ale może zostać zerwany, jeśli masz dobre powody. Mam na myśli BARDZO dobre powody.

Przy okazji: Złą praktyką jest pozwolić słuchaczowi się wyjąć. Dodawanie i usuwanie powinno być symetryczne. Tak więc słuchacz powinien zostać usunięty przez obiekt, który go zarejestrował. Jeśli masz dużo słuchaczy, wkrótce utkniesz.

Powiązane problemy