L'idea del pattern Observer è di consentire a un oggetto di registrarsi per gli aggiornamenti da un altro oggetto, senza che l'altro oggetto debba conoscere il tipo effettivo dell'osservatore.
In linguaggi tipizzati staticamente come Java o C ++, ciò avviene facendo in modo che la classe dell'oggetto che deve registrarsi per gli aggiornamenti, erediti dalla classe Observer o implementa l'interfaccia Observer. Questo è così che potrebbe essere considerato come un Osservatore e registrarsi come osservatore a qualsiasi classe che permetta questo, senza che la classe conosca il tipo effettivo dell'osservatore che registra.
La classe che consente agli oggetti di registrarsi per le notifiche (chiamata 'l'oggetto') fornisce un metodo pubblico registerObserver(Observer o)
, e grazie a Polymorphism è possibile registrare qualsiasi classe che erediti dalla classe Observer o implementa l'interfaccia di Observer.
La classe o l'interfaccia Observer avrà un metodo notifyObserver()
, che il soggetto può chiamare su tutti gli osservatori registrati ad esso - di nuovo, senza preoccuparsi del loro tipo concreto.
Questo ti mostra che non ha senso istanziare un Observer da solo. Ed è per questo che definisci la classe Observer come astratta, o in linguaggi di ereditarietà come un'interfaccia.
Inoltre, tieni presente che nei linguaggi ereditari singoli come C # o Java, è molto meglio definire un'interfaccia Observer, e non una classe Observer, perché se una classe eredita da Observer non può ereditare da qualcos'altro che è molto limitante. Tuttavia alcuni linguaggi ereditati da una sola interfaccia supportano le interfacce, quindi le tue classi possono implementare un'interfaccia Observer pur continuando ad ereditare da un'altra classe.
Un'altra cosa da ricordare è che concettualmente, una classe definisce un tipo di un oggetto mentre un'interfaccia definisce ciò che un oggetto può fare . Tutto ciò che interessa al tuo soggetto è che gli oggetti possono osservarlo , non gli importa cosa sono . Quindi concettualmente un'interfaccia Observer è un'opzione migliore di una classe (a meno che non si usi un linguaggio come C ++ che non ha interfacce ma ha ereditarietà multipla).