Observer vs Delegate/Events

barski

Junior Contributor
Joined
Apr 7, 2002
Messages
240
Location
Tennessee
The past couple of days i've been reading different web blogs\articles about the observer pattern vs delegates\events and all the articles basically end the same with delegates and events there's is no longer a need for the Observer Pattern and it also is less coupled than the observer. Since all the articles ended the same way i'm quite certain there is something i'm missing hence the post.


take this blog for example

I just don't see how this is less coupled because it seems to me for the observer to attach\observe there is going to have to be statement somewhere
Code:
MySubject.NotifyEvent+= new NotifyHandler(somemethodwithmatchingsignature)
. If that's true then the observer has to know the about that specific class. how can that be better?

like i said in all the articles i read delegate/events won so I know i'm wrong i just hope someone can explain why.
 
Subject does not know about the observer

Of course the observer must know what kind of object it is observing, otherwise it would be fairly pointless to observe it. However, with a delegate implementation, the subject does not need to know anything at all about the observer. This means that instead of having to implement a special IObserver interface as in the blog you referenced, any class can observe another by creating a delegate to one of its methods - any one of its methods with a matching signature.

Delegates/events are also a lot simpler as you do not need to write code to loop through each observer and invoke a method - this is all handled by the delegate implementation in the framework. Delegates on the whole are much simpler to use than the interfaces approach.

:)
 
okay this is where i'm getting lost. the observer doesn't need to know
anything about the subject other than it implements the interface. In the situation of window forms for example i doesn't need to know that its Form1,
Form2, Form3 etc...
 
Forms and Objects

That is correct. If you want to observe Form1 or Form2 then all you generally need to know is that the object is an instance of System.Windows.Forms.Form. If the form exposes some additional events, then the observer must know about them in order to attach to them. So if Form1 defines an event CustomEvent, an observer must know it is dealing with an instance of Form1, rather than just a Form, to attach to it.

To look at it at another way, all classes are subclasses of System.Object (excepting Object itself). The Object class defines no events, so if we treat Form1 as just an Object, there is nothing we can observe. However, if we know we are dealing with a Form, then we can attach to its specific events (as defined for a Form). Consequently, if we know we are dealing with a Form1, then we can attach to any events defined in Form1, such as CustomEvent.

C#:
object obj;

obj = new Form1(); //obj contains an instance of Form1

//But, all we know about obj is that it is an object,
//so we cannot attach to its Form or Form1 events

//Can attach to a Form event only if we cast obj to a Form
(obj as Form).Load += new EventHandler(...)

//Can attach to a Form1 event only if we cast obj to a Form1
(obj As Form1).CustomEvent += new EventHandler(...)

Note that at no point does Form1 need to know what, if anything, is observing it.

:cool:
 
Last edited:
The observer pattern and the "event pattern" aren't very different.

The observer pattern is very typical of Java. It is based on interface types, which is the only reasonable way that Java could implement an event driven model. The event pattern is based on a simpler type that is somewhat similar to an interface, the delegate. While both the interface and delegate point to an object and allow you to access methods of that object, different delegates of the same type can point to different methods of the same object (interfaces can not).

While the two patterns have their differences, the fundamental aspects of the two are the same. The use of delegates only allows us to treat different events more independently. (We don't need to declare two entire interfaces for each type of event, and we can use the same delegate type for more than one event of a class. In other words, much less code.) The fact remains, though, that the two patterns rely on the same principal. Indeed, the "event pattern" is really nothing more than a different form of the observer pattern.

MrPaul said:
Note that at no point does Form1 need to know what, if anything, is observing it.
This is a common misconception (or oversimplification). As the linked-to blog points out, "observer pattern" is a somewhat misleading name. The observer pattern is ultimately based on call-backs. In other words, the object being observed actively invokes all of the handlers to its events, hence it must know exactly who is handling which events. Form1 does indeed need to know what is observing it. DotNet does makes the process seem much more passive by providing a standard mechanism for objects to subscribe to events (using .Net event metadata and VB and C#'s simplified event systems) and automating the process of iterating through an invocation list. The fact remains, though, that in order to be observed, an object must maintain a list of objects that are observing it and invoke their handlers when an event occurs.
 
Delegates vs Interfaces

marble_eater said:
In other words, the object being observed actively invokes all of the handlers to its events, hence it must know exactly who is handling which events.
...
The fact remains, though, that in order to be observed, an object must maintain a list of objects that are observing it and invoke their handlers when an event occurs.

Sure, sure. These things must be happening behind the scenes, but we don't have to worry about them. My point was that the developer of Form1 doesn't need to consider what might be receiving events unless they want to. In the same way we would say Form1 doesn't need to worry about throwing NullReferenceExceptions, or a whole host of other similar things, as they are also handled implicitly by the framework. It is all just levels of abstraction.

One major advantage of delegates over interfaces is the ability to attach to only the events we are interested in. If we were required to implement an interface to handle Form events, that would involve implementing around 90 methods, most of which would be empty. This is how it is done in VB6, using hidden interfaces, although classes are not required to contain every event method (those missing are implemented implicitly by the compiler).

:cool:
 
MrPaul said:
Sure, sure. These things must be happening behind the scenes, but we don't have to worry about them. My point was that the developer of Form1 doesn't need to consider what might be receiving events unless they want to.
That is entirely true, but my point was on the conceptual end (which includes what is going on behind the scenes). I was comparing and contrasting the two design patterns, not the DotNet implementations. The observer, somewhere, somehow, needs to know who is receiving events is all I was saying, even if the developer doesn't know.
 
marble_eater said:
The fact remains, though, that in order to be observed, an object must maintain a list of objects that are observing it and invoke their handlers when an event occurs.
This is only true in some implementations of the observer pattern (and even then, it is extremely loosely coupled). When looking at the observer from a pub-sub perspective it simply is not true that the subject must know anything about its observers. (What MrPaul was saying I beleive.)

And by "event pattern" that's really all we're talking about here...publish-subscribe. This is one way to think about the observer pattern.


marble_eater said:
The observer pattern and the "event pattern" aren't very different.
They are actually the same design pattern, just different implementations. The reason using events is generally considered better is because .Net takes care of all the hard parts of implementing your own observer (the tiny ins and outs that you haven't even thought of yet) for free. I think both MrPaul and marble_eater implied this in their earlier posts.

As marble_eater said, by using events/delegates you are still implementing the observer pattern, you’re just doing it with a whole heck of a lot less code.
 
mskeel said:
They are actually the same design pattern, just different implementations.
marble_eater said:
Indeed, the "event pattern" is really nothing more than a different form of the observer pattern.

mskeel said:
we're talking about here...publish-subscribe. This is one way to think
about the observer pattern.
From every thing I can find, the observer pattern "is a publish/subscribe mechanism where an objects can register to be notified of state changes."* Anything beyond the scope of that might be an observer scenario, but I don't think that that would be enough for it to be considered an implementation of the observer pattern.

Also, how can the observer pattern be implemented realistically without the observer publishing events in such a way that it must know who is subscribed to what observations? I suppose you could have an intermediate layer that receives both subscriptions and dispatches publications, but this would be in the spirit of abstraction or encapsulation rather than in the spirit of eliminating the publisher's knowledge of subscribers (and such implementation would most likely provide a mechanism to identify subscribers). Besides that, I would say that it is generally accepted that publishers manage their list of subscriptions in the observer pattern. I am not the authority, but I would say that the intermediary would make this a modified observer pattern (I think that this would actually be considered a mediator pattern).

The observer could constantly poll the observed object, but more often than not this is inefficient and cumbersome, and, not being a publish/subscribe mechanism, wouldn't (I don't think) be considered an observer pattern.

So perhaps it is possible for the publisher to be oblivious to subscribers, but this is rarely the case and is at best a close approximation to the observer pattern (because I always need to be right and get the last word in).
 
thanks for all the input. It did help me out. I completely see and understand that it is significanlty less plumbing but the thing i still don't see is how delegates are less coupled. In almost all the blogs\articles i read it was stated as fact that delegates are less coupled. Once again thanks for all the input... i'll read a few more articles and maybe i'll get how delegates are less coupled
 
marble_eater, I did some more reading on this as well and I think I was leap frogging my own thoughts a little. The observer pattern itself is accomplished through a single design. The same effect can be accomplished by taking advantage of various features of .Net, such as events and delegates, but that is not necessarily the same as an implementation of the observer pattern. I was looking at the design from a conceptual perspective and filling in the blanks because I wouldn't actually design an application that way when I have events available. The bottom line here, you were correct and I think I misinterpreted some of what you were saying.

Here's an interesting thought. Similarly to how the iterator pattern is a part of the .Net framework already, it seems likely that .Net's event system is probably an implementation of the observer pattern. Any thoughts?
 
Quite frankly, I have a tendency to arrogantly make certain assumptions as I go along without verifying my statements (as I think of it, although leap frogging one's though, I suppose, would be another way of putting it if one were less arrogant than I), as I think we all do to some extent (but I am the king and the master, which is why I always win arguments... unless a moderator closes the thread... oops, didn't mean to type that... or that). For the sake of actual intelligent discussion, however, I will stick to the Observer Pattern as discussed by Wikipedia.

Wikipedia does list the DotNet event system as an implementation of the observer pattern. Generally, the observer pattern is based on interfaces (since they allow a class to implement multiple observation scenarios), however base classes should also be acceptable.

If we were to look at DotNet events as an observer pattern, the event handlers would (obviously) be considered the subscriber, where it could be said that any method that matches an event signature implies a subscriber interface (as they do indeed, provided that we regard delegates as a simplified form of the interface type). The publisher, on the other hand, is not based on any standard interface composed of pure code (pure VB or pure C#), but, rather, the publisher is implemented in part as language (C#/VB) code, in part as MSIL code created by the compiler, and in part by DotNet metadata. At run-time all we really have on the publisher end is the invocation of a function pointer.

Although the spirit here is the same as the observer pattern, it is difficult to come to the conclusion here that we do have a representation of a publisher interface. It ultimately breaks down to the question, then, of whether the pattern must be based upon interfaces.

I would say that it depends on your definition of the observer pattern (Is there a correct definition? If so, I would love to see it.) and how loosely you interpret it. Wikipedia does not list an interface or base-class implementation as a requisite for an implementation of the observer pattern. It states that publishers generally maintain a list of observers, who must register and unregister, and use a call-back mechanism. Based on this description, DotNet events certainly qualify as an observer pattern.

We haven't wandered off topic, have we?
 
I would say that Mr. Fowler (et. al.) would be cringing right now. The whole point of patterns was to get an idea across, and not worry too much about implementation. It was the recognizing of something re-usable and giving it a name so that people can discuss things using the same language.

To that end, a delegate/event is just the implementation of the observer pattern. There shouldn't be discussion that delegates replace the pattern - they just implement it easily. I'd say kudos to MS for developing the code so we can just declare delegates and use them.

Now, if they could solve it so I don't have to check for null before I call my delegate (from the subject) - seems like such a pain, if you ask me and I KNOW they can fix it, but they don't :)

-ner
 
Nerseus, maybe you should be using VB so you can take advantage of the RaiseEvent keyword. There is an advantage to being able to check if there are handlers attached (checking for null). For example, you don't need to bother creating your EventArgs object if there are no handlers (which is not really a huge deal, but just think about how many events are thrown in WinForms apps). You can't take advantage of this in VB. Of course, it would be nice if we didn't have to check.

As far as the discussion on whether DotNet events are an implementation of the observer pattern, I think the discussion does have its merits. The question, really, is whether the DotNet event system is the idea expressed by the concept of the observer pattern. The observer pattern an OOP concept, and DotNet events are not 100% OO (as nice as delegates are, they aren't very OO). So it is hard to decide whether they are the same idea. Does it really, truly make a difference? Of course not. But I enjoy talking about it.
 
Back
Top