日期:2014-05-17 浏览次数:21302 次
Delegate offers some nice features of observable pattern, however, there are some limiation on the delgate implemented observable patterns.
?
?
For onething, there is no way to know when the subject no longer tick; the subject may become out of interest if it does not tick updates; But with the passive mode of delegate, you do not know that a subject is become inactive as the pattern itself is passive (there are some workaround , indeed by you provide another event to nofity that the subject is beome inactive);
?
For another, there is no way to descrimate against a valid udpate from error conditions, using some sentry value as the update event args could serve in some cases, but that is a botch/tinker/bumble/bungle rather than good solution, it is a smell design to intermingle the normal message channel with the error message channel;
?
for yet another, there is no way to know when/how to remove the IObserver from the notification list, a simple -= may unsusbscribe the event listener, but there would exist a huge amount of house keeping work that needs to be addresseed when an Observer go out of scope. Better, a Disposable is better in situation like this;?
?
?
IObservable<T> and IObserver<T> pattern provides the cure;
?
It has provide the following.
the return value of IDisposable, which satisify the the question of "how to remove teh IObserver from the notification list";
this has the functionality of telling the observers when the subject (provider) will/has become inactive. and on receiving the information, teh IObserver can use the IDispose method that it receives in the Subscribe step to unsubscibe itself from the notification and do the proper uninitialization.
?
Below shows the code an example IObservable<T> implementation, the T is of type Location, which represent some Location information.
?
?
?
namespace PushBasedNotificationTest { public struct Location { double lat, lon; public Location(double latitude, double longitude) { this.lat = latitude; this.lon = longitude; } public double Latitude { get { return this.lat; } } public double Longitude { get { return this.lon; } } } }?
?
LocationTracker is our impl ?of IObservable<Location>, here it is:
?
?
namespace PushBasedNotificationTest { public class LocationTracker : IObservable<Location> { public LocationTracker() { // initialize the list of Observers to the Updates observers = new List<IObserver<Location>>(); } // you need a collection of Observers // on which you can send the notification private List<IObserver<Location>> observers; // Subscribe an observer (IObserver<T>) to the observer list // notice the return value of the Subscribe method, // which is of type IDisposable. // normally the Observer will store the return value // and call the Dispose method from the IDisposable interface // the common work done in the Disposable method is to remove itself from