Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Implementing observer pattern with events

I am working on a Silverlight application where I made excessive use of the observer pattern. In my implementation I have created two interfaces IObservable<T> and IObserver<T>. The former contains methods to attach and detach observers to the observable. The latter has a method Notify(IObservable<T> observable, ...) that is called by the observable passing itself as parameter via observer.Notify(this, ...) when the observable has changed its state.

Now I have stumbled upon "events" and for me it seems pretty much as if this were an implementation of the observer pattern, just with delegates instead of the aforementioned Notify-method. Is that right?

I do not know much about delegates and do not want to spend hours on rewriting my code just to end up with code that does the same thing as it already does. On the other hand events might be superior to the interface-based observer pattern. Am I missing something?

like image 207
JCvanDamme Avatar asked Dec 16 '14 14:12

JCvanDamme


1 Answers

Events are an implementation of the observer pattern.

An event is implemented as a list of methods to be called when the vent is raised.

Delegates are method references: in contrast to Java, C# offers a way to refer to a method.

It's not a priori better to use events than implement the observer pattern oneself. But events offer a quite generic way to do it, and are in many cases highly optimized for the task, thus give a more efficient and convenient way organize this.

A delegate is defined by the signature of the expected method. For instance with:

public delegate void FooMethod (Bar x, Baz y);

You define a delegate for void methods given a Bar and a Baz. So if you have an instance of the following class:

public class Qux {

    public void Method (Bar x, Baz y) {
        //do something
        return null;
    }

}

Then you can refer to the method:

Qux q = new Qux();
FooMethod fm = q.Method;

An event is thus a list of delegates with the same signature:

You define an event as:

private event FooMethod SomeEvent;

You can add delegates (listeners) by using the += operator:

SomeEvent += q.Method;

remove the delegate by the -= operator and call the event with:

SomeEvent(new Bar(), new Baz());

As if you call a single method that does the dispatching.

By calling the event, all the registered delegates will be called, in the order of registration.

Note: By calling SomeEvent(new Bar(), new Baz()); this does not mean every delegate receives new instances: the instances are constructed first and shared over all delegate calls.

Conclusion: I think the C# designers did a good job introducing observer patterns since the programmer is no longer responsible to program it correctly his/herself. Furthermore the events are easy to understand and use convenient syntax. In special situations however programmers can be required to implement an observer him/herself. But these are very rare occasions.

like image 99
Willem Van Onsem Avatar answered Sep 29 '22 09:09

Willem Van Onsem