In the delegate pattern, only one object can directly listen to another object's events. In the observer pattern, any number of objects can listen to a particular object's events. When designing a class that needs to notify other object(s) of events, why would you ever use the delegate pattern over the observer pattern? I see the observer pattern as more flexible. You may only have one observer now, but a future design may require multiple observers.
-
4What do you mean by "delegate pattern"? If you're talking about something like .net's delegates, you can have as many subscribers as you like.– CodesInChaosCommented Dec 2, 2012 at 9:45
-
Related, though more focused on Cocoa: NSNotificationCenter vs delegation( using protocols )?– mouvicielCommented Jan 6, 2014 at 9:54
5 Answers
There is no delegate pattern per se. I am going to assume you mean Delegation Pattern.
As I understand it, they're the complete reverse of each other and used for different purposes.
Generally, with an Observer Pattern, any number of observer objects will listen to an event on a second object and act on the event. The second object has no knowledge of its listeners. It just calls out to them.
A delegate object is passed to the second object which calls methods directly on the delegate. And therein lies the advantage you're looking for. Rather than sending a single message to multiple listeners, it has complete control over a single object (at a given time). See also Inversion of Control.
You're looking at things incorrectly. An observer sees that a particular event occurs. It does not impact it, or own it. A delegate handles a particular event, and has ownership of the handler, even if the delegator owns the interface to the event.
-
1A delegate really is nothing more than an observer of an event. A delegate does not need to "handle" anything. It can safely do nothing at all and won't (or at least should not) affect the instance that triggered the event. Commented Dec 2, 2012 at 9:49
-
5@MarjanVenema - if object A isn't delegating the responsibility for the event to object B, you're not using the delegation pattern: you're using the observer pattern with only one observer.– TelastynCommented Dec 2, 2012 at 14:38
-
Yes, that is what I was thinking of. I understood delegated to be the event signature types to be used by the subscriber of an "OnWhatever" event. Apparently delegates in C# are not single-subscriber as they are in for instance Delphi. Commented Dec 2, 2012 at 19:03
-
@Marjan Venema "A delegate really is nothing more than an observer of an event." -- it depends what language you're talking about. In Objective C, some delegates are responsible for providing data -- e.g. data delegates -- and an object missing a data delegate has no data to present. In those cases, there is delegation happening, distinct from the act of just observing something.– occulusCommented Dec 2, 2012 at 23:47
-
1@occulus: thanks for the clarification. Pity that languages can't agree on terminology... Talking about programming in a language agnostic way gets a bit hard when people understand different things for the same words. Commented Dec 3, 2012 at 8:04
That's a question of several trade-offs.
Trade-offs:
- flexibility (in terms of having n > 1 delegates/observers)
- cost of sending a message
- resilience (ability to sustain unavailability of delegate/observers)
- ease of use
Delegate pattern:
- not very flexible - adding more than 1 delegate is not possible (implies some form of "multi-delegate" i.e. observer pattern)
- sending a message is cheap, O(1) - same cost as calling any other function or method (no look-up, message queue or other infrastructure required)
- usually not resilient - delegates are expected to be present and do their part of the work, i.e. the sender tends to fail if not delegate is known
- easy to grasp, easy to implement
Observer pattern:
- very flexible - adding n > 1 observers is expected by design
- sending a message has a cost implied by number of observers, O(n), i.e. n observers take n time and messages (at least in a naive implementation)
- usually resilient - observers are not generally expected to do any work on part of the sender. That is even if there is no observer the sender is unaffected
- can become rather complex to grasp, in particular of observers are expected to react to messages (does the order matter?, which observer responds in which way?)
The delegate pattern, as I understand you, is know as the event handler mechanism in other languages, for example Delphi. As such it simply is an implementation of the observer pattern with a major restriction: only one listener at a time.
The disadvantage of event handlers or delegates is obvious: only one observer.
The advantage is not so obvious: performance. With an observer pattern you can add many observers. When an event occurs that the observers need to be notified about, you will need to enumerate the observers and send a notification to each. This can quickly bog down any observed instance, especially when the number of events that require notification is significant as well.
-
Huh? The C# delegate is just the signature of a method as a variable type (equivalent to, for example,
int (*my_int_f)(int)
in C). I've always thought they'd have made that easier to understand by making it work more like struct/enum. An event is a hook for a flexible array of listeners, using a single delegate signature. You could do that without an event (which is why I assume the OP meant Delegation Pattern, which is very different), but the language is making it easier for you.– pdrCommented Dec 2, 2012 at 14:10 -
hmm. Not that well versed in C# yet. I understood delegates to be the equivalent of event signature types as used by "OnWhatever" events in for instance Delphi. So C# events can be subscribed to by multiple listeners? Commented Dec 2, 2012 at 19:00
-
The generic Action<T> is a delegate. It has nothing to do with events, it's a variable that gets passed around. And yes, multiple listeners can listen to one event.– pdrCommented Dec 2, 2012 at 20:07
-
ok thanks, hope I can keep it straight ... :-) Took out the C# reference and focused more on the event mechanism. Commented Dec 2, 2012 at 20:16
This is an old post but I'm going to chime in anyway because the other answers don't deal with what's happening when using either pattern, they seem to be more about theory than practice.
How Delegation and Observer Work
With Delegation the delegator picks exactly who is going to respond to a particular event the moment the source of the potential event is created. You could think of this listener as a single observer. In the case of the Observer pattern the observer picks who it's observing whenever it feels like it; so the dependancies are reversed when it comes to observer vs delegation. With the observer pattern think of a newspaper and subscribers as observers. The observers are in control of when the relationship gets created. With delegation think of an employee and an employer. The employer is in control of when the relationship gets created and exactly who is in charge of specific events. Employees can't pick what tasks they are working on...generally.
Some argue delegation can have one observer but I think the real difference between the two is how event handling is assigned. You will never see a delegate register for an event. It will never know its even handling the event till it happens and the delegator calls a public method on it.
Delegation Advantage
This pattern is very rigid and with most regid designs its simpler and generally more robust. It forces you to declare your event handler up front at the time of initializing the source of the potential event. If you need someone to direct traffic you assign a traffic director before you open up the street. In the case of the observer you would let the traffic cop choose when to direct traffic any time he or she felt like it.
Delegation Disadvantage
The disadvantage of this design is that it's not flexible. If you were implementing some code for subscribing for a newspaper the newspaper/delegator would have to identify exactly who can read the news stories the second they are created. With the observer pattern they can be registered later at any time and the newspaper will only have to know that a new person has signed up.
When To Choose Delegation?
When you need one specific observer(s) for sure and there is no reason for you to change who is observing then the rigid design of the delegation pattern will be beneficial.
For example, you need a class/object to handle creating a pop-up for a specific error. There aren't many reasons why at run-time you would need to switch who is handling a specific error so delegating the "Out-of Memory" error to a single entity would make sense. Creating an array of potential handlers and then having those handlers register for the "Out-of Memory" error wouldn't make much sense; that would be an example of using the observer pattern in this situation. At run-time you might want to change what methods get called or what "delegate" gets called for variable events but swapping out an event handler for a specific event at run-time isn't normal.
Its not impossible to swap delegates like you would do in the observer pattern, its just complicated. In the real world perhaps you want to swap traffic cops so a new delegator is handling traffic. One could argue that a better design would make original delegate a police station and not a single police officer but I digress...