.NET Framework 4.0 offers a set of new features focused on Observable/Observer design pattern. Actually, such pattern is a subset of Publish/Subscribe design pattern. Such kind of patterns aim to provide a mechanism for push-based notifications.
The idea turns around two new generic interfaces IObserver<T> and IObservable<T> . Whilst IObservable<T> provides all the functionality for the publisher, IObserver<T> does the same for subscriber. You will find that publisher and subscriber are also known as provider and observer. Whatever name is used for, keep in mind what each item is supposed to do, otherwise you will feel confused.
- Publisher –> Provider –> Observable
- Subscriber –> Observer
Notice that both interfaces are generics by <T>. Actually, IObservable is covariant with <T> whereas IObserver is contravariant with <T>. The reason is that whilst IObservable could provide push-based notification methods to the indicated type <T> and more derived <T> types, the IObserver only could observe such derived types from <T’> to <T> where <T’> is the derived type of <T>, i.e. IObserver could use <T> and less derived types. The contracts of both interfaces are declared as follows:
I wish to be observed
That said, the main target of an observable object is to be observed by a bunch of observers. Observable owns just one method used for subscribing in an observer. On the other hand, each time an observable object push a new notification it would be caught by OnNext observer’s method. Let’s see an example.
Suppose we have a simply class called Car which describes a racing car.
Besides, a simply class which describes a Race.
Then, our goal is monitoring a car racing. Let’s say that such car racing is Nascar which will contain a Race type object and such Race object will contain a generic list of participants Cars, as well. What we aim to monitor is the Nascar car racing so we may create a class NascarRace which will be observable for car racing journalist, let’s say NBC and BBC. Thus, such journalist would became nascar’s observer.
The nascar race could be described as follows:
Note that NascarRace class constructor sets up three cars which are going to participate to the competition. On the other hand a new thread is created and launched once the competition starts up. ThreadStart delegate points to a method called Running() and this method will hold the racing timeline. The total laps are set by default at 40 so during 40 laps all three cars will be gathering elapsed time and for each lap all the observers are going to be notified. RaceMonitor will be displaying race results in ascending order. Before next lap, thread gets slept for a 1 second in order to give more emotion to simulated nascar racing
Now, I wish to observe
On the other hand journalist or anyone else whom aims to be an observer would be described through RaceMonitor class described as follows:
The observers will be represented by RaceMonitor class and will be subscribed to NascarRace through Subscribe() method in the main method’s program.
The main program would be:
And the final standings!!
Check how push notifications to IObserver<Race> object are made at following sequence diagram of NascarRace.Running method. All take place into lap control loop.
Deferred calls are made since we are actually using LINQ’s method extension for iterating both Cars and Observers (RaceMonitor objects).
Here you are complete code listing: