Questo è il pattern Observer - è la stessa identica cosa.
I have used some kind of "listeners" where I have an interface implemented by classes that need to be notified of some event (e.g.: CurrencyListener, with a method currencyUpdated(Currency currency))
Nel pattern Observer, hai un'astrazione (un'interfaccia o una classe base) Observer che definisce le cose che l'osservatore può osservare (o ascoltare). Il tuo CurrencyListener è Observer .
L'altra parte del pattern è Observable , che è l'oggetto che invia notifiche, che possono essere o meno un'astrazione, o parte di una gerarchia. Ad esempio, il modello non richiede che siano presenti le sottoclassi ConcreteObservable. Nel libro Modelli Go4, uno dei ruoli per un oggetto ConcreteObservable è descritto come
"stores state of interest to ConcreteObserver objects."
Se un ConcreteObserver non può aver bisogno di uno stato speciale, o può funzionare con l'interfaccia fornita dalla classe base Observable, allora non c'è bisogno di per un ConcreteObservable.
Then, the object that needs to send a notification, has a list of listeners (List) and just iterates over this list invoking the currencyUpdated(Currency currency) method
Observer fornisce metodi per Observables / Listeners per registrarsi con esso e mantiene internamente una collezione di questi listener. Questo è esattamente ciò che fa il tuo oggetto.
Ancora una volta, è solo il classico modello di Osservatore. Gli osservatori e gli osservabili sono indipendenti l'uno dall'altro perché dipendono entrambi dall'astrazione fornita dall'interfaccia Observer e perché si basano sul codice client che li utilizza per collegare gli osservatori / ascoltatori con l'osservabile.
P.S. C'è una serie di variazioni sul pattern e un numero di feature in diverse lingue che sono solo il pattern Observer travestito. Ad esempio, in C #, gli eventi sono chiaramente una variazione del modello. Un altro esempio di variazione potrebbe essere quello che viene solitamente chiamato Messenger (o Event Aggregator, come lo chiama Martin Fowler), può essere trovato in alcune librerie e framework - è una classe che funge da intermediario tra gli osservatori e gli osservabili . La struttura è leggermente diversa, ma è basata sul pattern Observer; infatti, il libro Go4 descrive qualcosa di simile vicino alla fine della sezione Implementazione nella descrizione del pattern (lo chiamano ChangeManager).