@PanamaJoe: Przykład praktycznego wykorzystania:
Piszesz aplikację, która ma wyświetlać listę ticketów w Jira.
Robisz "jakiś" mechanizm, który dba o to, żebyte tickety znalazły się w liście, były dociągane nowe, zamknięte usuwane itd.
Dorabiasz widok gdzie jakaś kontrolka ma wyświetlać aktualną zawartość listy. Widok rejestruje listenera w tej liście, i jest powiadamiany jeżeli zaistnieje konieczność odświeżenia tego co wyświetla.
Za chwilę pojawia się wymaganie biznesowe, że jak pojawi się coś nowego, to masz wyświetlić jakieś powiadomienie, a oprócz widoku listy masz też zrobić drugi panel, który wyświetli te dane ale w postaci kafelków - zmiana jest banalna.
Okazuje się, że aplikacja zaczyna lagować, bo wszystko zrobiłeś na pojedynczym wątku, a pobranie nowych ticketów stało się czasochłonne - podział na wątki również jest banalny.
Firma przepina się z Jira na RedMine ;) , zmieniasz jedynie mechanizm zasilający, cała reszta pozostaje bez zmian.
Trafiasz na ten jeden przypadek na milion, kiedy faktycznie ma znaczenie czy użyłeś ArrayListy, czy LinkedList zmieniasz jedną linijkę w kodzie.
W praktyce takie nasłuchiwanie zmian jest potrzebne dość często, przykład z listą jest akurat dlatego, że jest prosty do zrozumienia.
--edit
Dam też przykład jak można rozwiązać problem:
public class ObservableList<T> implements List<T>{
private final List<T> underlying;
private final List<ListListener> observers = new ArrayList<>();
//tu następuje implementacja wszystkich metod List:
public int length(){
return underlying.length();
}
........
//dla metod które coś zmieniają:
public void clear() {
underlying.clear();
observers.forEach(ListListener::onClear);
}
}
//do tego dodanie możliwości rejestrowania listenerów
public void addListener(ListListener listener){
observers.add(listener);
}
Pewnie warto byłoby trzymać te listenery dodatkowo zapakowane w WeakReference (bo o dodaniu to pamięta każdy, o wyrejestrowaniu już nie zawsze), można by to proxy rozdzielić na DefaultProxy
z implementacjami 1:1 i dopiero dziedzicząc po nim nadpisywać konkretne metody.