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?
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.
Related
I'm learning how to incorporate IObservable into my code. Below are two different approaches for a simple class that prints out the most recent word from an IObservable<string>. Which is the cleaner approach? I don't like WordPrinterWithCache because it introduces additional state (the _lastWord) variable and the interesting code is now scattered throughout the class. I prefer WordPrinterWithExtraSubject because the interesting code is localized to the constructor. But mostly it seems more consistently functional and "reactive"; I am reacting to the combination of two "events": (1) a new word being emitted, and (2) the invocation of the PrintMostRecent method.
However I have read that using Subjects is not desirable when it is not strictly necessary and I am introducing an unnecessary Subject<Unit>. Essentially what I'm doing here is generating an observable from a method call so I can use the observable combinator functions in more places. I like the idea of building up my code using the observable combinators and subscriptions rather than using "old-style" method invocation trees. I don't know if this is a good idea.
public class WordPrinterWithCache
{
string _lastWord = string.Empty;
public WordPrinterWithCache(IObservable<string> words)
{
words.Subscribe(w => _lastWord = w);
}
public void PrintMostRecent() => Console.WriteLine(_lastWord);
}
public class WordPrinterWithExtraSubject
{
Subject<Unit> _printRequest = new Subject<Unit>();
public WordPrinterWithExtraSubject(IObservable<string> words)
{
_printRequest
.WithLatestFrom(words.StartWith(string.Empty), (_, w) => w)
.Subscribe(w => Console.WriteLine(w));
}
public void PrintMostRecent() => _printRequest.OnNext(Unit.Default);
}
The actual scenario in my code is that I have an ICommand. When the user invokes the command (maybe by clicking a button), I want to take action on the most recent value of a specific observable. For example, maybe the ICommand represents Delete and I want to delete the selected item in a list that is represented by an IObservable<Guid>. It gets ugly to keep a bunch of "last emitted value" cache variables for each observable.
The approach I'm leaning toward is an ICommand implementation kind of like what you see below. This allows me to write code like deleteCommand.WithLatestFrom(selectedItems,(d,s)=>s).Subscribe(selected=>delete(selected));
public class ObservableCommand : ICommand, IObservable<object>
{
bool _mostRecentCanExecute = true;
Subject<object> _executeRequested = new Subject<object>();
public ObservableCommand(IObservable<bool> canExecute)
{
canExecute.Subscribe(c => _mostRecentCanExecute = c);
}
public event EventHandler CanExecuteChanged; // not implemented yet
public bool CanExecute(object parameter) => _mostRecentCanExecute;
public void Execute(object parameter) => _executeRequested.OnNext(parameter);
public IDisposable Subscribe(IObserver<object> observer) => _executeRequested.Subscribe(observer);
}
So as a general rule (guideline), I strongly suggest not having an IObservable<T> as a parameter to a method. The obvious caveat being if that method is a new Rx Operator e.g. Select, MySpecialBuffer, Debounce etc.
The theory here is that IObservable<T> is a callback mechanism. It allows something to callback to another thing that it otherwise knows nothing about. However in this case, you have something that knows about both the IObservable<T> (parameter) and the other thing (WordPrinterWithCache).
So why is there this extra layer of indirection? What ever it was that was pushing values to the IObservable<T> could just instead call a method of the WordPrinterWithCache instance.
In this case, just call a method on the other thing
public class WordPrinterWithCache
{
private string _lastWord = string.Empty;
public void SetLastWord(string word)
{
_lastWord = word;
}
public void PrintMostRecent() => Console.WriteLine(_lastWord);
}
Now this class starts to look rather pointless, but that might be ok. Simple is good.
Use Rx to help you with layering.
Upstream layers depend on down stream layers. They will directly call methods (issue commands) on the downstream layers.
Downstream layers wont have access to upstream layers. So to expose data to them they can either return values from methods, or can expose callbacks. The GoF Observer patter, .NET Events and Rx are ways to provide callbacks to upstream layers.
While I'm not sure I'd use the term "turning a method call into an observable event", I have been a fan of using fully declarative, functional and Rx driven code for a while now.
Your description of an ICommand implementation matches very closely with one I wrote a couple of years ago and have used many times and very successfully since. Furthermore, this has become the basis for a pattern I refer to as "Reactive Behaviors" which provides numerous benefits. From my blog:
Promotes behavior driven development and unit testing.
Promotes functional and thread safe programming practises.
Reduces the risk of (and if done well, can eliminate) side effects as specific behaviors are isolated in a single well named method.
Stops 'code rot' as all behavior is encapsulated within specifically named methods. Want new behaviour? Add a new method. Don't want a specific behavior anymore? Just removed it. Want a specific behavior to change? Change the one method and know that you haven't broken anything else.
Provides concise mechanisms for aggregating multiple inputs and promotes asynchronous processes to first-class status.
Reduces the need for utility classes as data can be passed through the pipeline as strongly typed anonymous classes.
Prevents memory leaks as all behaviors return a disposable that when disposed removes all subscriptions and disposed all managed resources.
You can read the full article on my blog.
This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
What is the difference between a delegate and events?
This question I got at an interview and I still don't know what the answer should be.
I would appreciate any thoughts!
I have an article on pretty much exactly
In brief, you can think of an event as being a bit like a property - but instead of having get/set operations, it has add/remove. The value being added/removed is always a delegate reference.
Delegates themselves support operations of:
Combine (chain multiple delegate instances together)
Remove (split them up again)
Invoke (synchronous or asynchronous)
Various things to do with finding out the target, invocation list etc
Note that delegates themselves are immutable, so combine/remove operations return a new delegate instance rather than modifying the existing ones.
The other answers so far are all quite good. Here's another way to think about it.
What's the semantic difference between a property and a field? I don't mean what are the technical differences, like a property is actually a pair of methods, blah blah blah. I mean, as far as understanding the meaning of a program goes, what is the difference?
A property is usually a public member of a class, and it represents a property of the thing being modelled. That is, you want to make a model of a newspaper so you make a class Newspaper and you give it a property Publisher. The publisher is a property of newspapers, so Publisher is a property of the Newspaper class.
A field is usually an implementation detail of a class. Maybe the Publisher property is actually implemented as a field. But newspapers do not have "fields", so you don't expose the publisher field as a public member of the Newspaper class; you use it as a private implementation detail of the Publisher property.
Events and delegates are somewhat analogous. An event is something in the model. A button is a thing that can inform you when it is clicked, so the Button class has a "Click" event. The delegate that actually does the informing is the implementation detail of the event.
Basically, a delegate is just a wrapper around what would be a function pointer in C (or a list of function pointers).
An event is an even higher level abstraction that wraps the concept of a delegate together with methods to subscribe and unsubscribe a method to such delegates.
An event is a “property” that exposes an add and remove method (invoked via += and -= in code) to add/remove subscribers to a delegate list.
A delegate is similar to a function pointer in C/C++. It holds a reference to a method and to an object instance (if the method is non-static). Delegates are usually multicast, i.e. they hold references to several object/method pairs.
An event is a notification mechanism, based on delegates. The only thing it exposes publicly is a pair of methods (add/remove) to subscribe to or unsubscribe from the notification. A delegate type is used to define the signature of the handler methods, and the list of subscribers are (usually) stored internally as a delegate.
I readily admit that this reply doesn't compare the difference between delegates and events. However, I think with the replies that others have given for Events along with a bit more detailed explanation on delegates, you will see the difference between the two.
More specifically, once you have a clearer understanding of delegates, I think you will gain a conceptual difference between delegates and events.
What has helped me in understanding what a delegate is, is thinking of them as nothing more than a container for a single method.
To conceptualize how a delegate is a 'container' of a method, review this example that makes use of a delegate to invoke three different methods - Note that although the same delegate instance is used to invoke three different methods, the delegate instance will only contain (or target) one method at any given time.
class Program
{
delegate void MyDelegate();
static void Main()
{
//Notice how we use the same delegate instance
//to target different methods of the same signature
MyDelegate myDelegate = new MyDelegate(MethodA);
myDelegate(); //Invoke the method
myDelegate = MethodB;
myDelegate();
myDelegate = MyClass.MethodZ;
myDelegate();
Console.ReadLine();
}
static void MethodA()
{
Console.WriteLine("Method 'A' is doing work.");
}
static void MethodB()
{
Console.WriteLine("Method 'B' is doing work.");
}
class MyClass
{
public static void MethodZ()
{
Console.WriteLine("Method 'Z' of MyClass is doing work");
}
}
}
You'll notice that the delegate in the example can contain/target any method that has the same signature as the delegate (returns void and takes zero parameters in our example). If you pause here and digest that principle, you're off to a good start at understanding delegates.
With that being said, what confused me about delegates is when I would ever explicitly implement delegates in my code. The example program above explicitly makes use of a delegate, but there is no practical reason to do so since the Main() method could just as well have called the target methods directly - i.e. we could have just done...
static void Main()
{
MethodA();
MethodB();
MyClass.MethodZ();
Console.ReadLine();
}
So what is an example of when we would implement a delegate explicitly? Jon Skeet helped me with answering that question when he said
...you can think of a delegate type as
being a bit like an interface with a
single method.
Knowing that a delegate is a container for a method and, now, considering that a delegate is like an Interface with a single method, consider this:
Say we have a program that will start the engines of different types of vehicles - Car, Motorcyle, and Airplane.
Our program will consist of vehicle classes - one class for each vehicle type. Each vehicle class is responsible for starting its own engine. In addition, similar to implementing an Interface, each class will make sure that its method that starts its own engine, will have a specified signature that all other classes (and the Main) agree upon.
So we have something like this:
class VehicleProgram
{
//All vehicle classes implement their own engine starter method that has this signature
delegate void StartEngine();
static void Main()
{
//The Main doesn't know the details of starting an engine.
//It delegates the responsibility to the concrete vehicle class
foreach (StartEngine starter in GetVehicleStarters())
{
starter(); //Invoke the method
}
Console.ReadLine();
}
static List<StartEngine> GetVehicleStarters()
{
//Create a list of delegates that target the engine starter methods
List<StartEngine> starters = new List<StartEngine>();
starters.Add(Car.StartCar);
starters.Add(Motorcycle.StartMotorcycle);
starters.Add(Airplane.StartAirplane);
return (starters);
}
class Car
{
public static void StartCar()
{
Console.WriteLine("The car is starting.");
}
}
class Motorcycle
{
public static void StartMotorcycle()
{
Console.WriteLine("The motorcycle is starting.");
}
}
class Airplane
{
public static void StartAirplane()
{
Console.WriteLine("The airplane is starting.");
}
}
}
Since delegates hold methods, we were able to implement a design where the Main() simply gets a list of delegates then invokes the method. This design is very similar to how we implement Interfaces.
Read more on When to Use Delegates Instead of Interfaces
Here's a really good article on it.
http://www.akadia.com/services/dotnet_delegates_and_events.html
Basically, events provide for a tightly coupled publish subscribe paradigm, while delegates provide for a much more loosely coupled design.
Events are easier and more straightforward to use, though.
Delegates are nothing but a function pointer, where in the function gets called asynchronously But Events are nothing but notification. For example clicking button is an event, so for that you need subscribe for the click event of a button etc..
I'm working on a program that needs a Java object to have an event. I'm quite familiar with how this works in C#, having had enough experience to learn the pitfalls.
What are the pitfalls of working with events in Java? How are they different from events in C# 2.0?
Example: An object changed event to prompt a save from the owner object.
Note: Java 1.5
Related: C# event handling (compared to Java)
Java has no built-in concept of events, so you are best off using variations of The Observer Pattern.
In C#, you're supposed to do like this when you fire an event:
public event SomeDelegate MyEvent;
private void FireMyEvent(MyEventArgs args)
{
var deleg = MyEvent;
if (deleg != null) deleg(args);
}
... to protect yourself from concurrent modification (in case a thread removes an event listener between you checking the nullness of MyEvent and calling it). In Java, you'd use a CopyOnWriteArrayList instead to protect yourself from concurrent modification:
private final CopyOnWriteArrayList<MyEventListener> listeners =
new CopyOnWriteArrayList<MyEventListener>();
private void fireMyEvent(MyEventArgs args){
// Iteration is performed over a snapshot of the list, concurrent
// modifications from other threads are invisible to the iterator
// and will not cause ConcurrentModificationExceptions.
for (MyEventListener listener : listeners)
listener.eventOccurred(args);
}
As mentioned earlier, Java doesn't have delegates and events that C# has. But considering it's a "generalized" implementation of the Observer pattern (GoF) you can implement it on your own.
There are examples in the wikipedia page on how to implement the pattern with java.util.Observable and java.util.Observer. The general idea is to let classes that implement Observer to subscribe themselves to an Observable class.
I usually roll my own implementation since it is darn easy to do so, as you only need to make an interface declaring the methods that the "observable" class call to it's registered "observers". Here is a simple example of an observable class that can register SimpleObserver objects and perform some kind of event on them:
public class MyObservableClass {
List<SimpleObserver> observers = new ArrayList<SimpleObserver>();
/**
* Registers the observer
*/
public void addObserver(SimpleObserver observer) {
observers.add(observer);
}
/**
* Removes the registered observer (to be nice towards the
* garbage collector).
*/
public void removeObserver(SimpleObserver observer) {
observers.remove(observer);
}
/**
* Notifies the observers with the given data
*/
private void notifyObservers(String data) {
for(SimpleObserver o : observers) {
o.onEvent(data);
}
}
public void doSomething() {
// Do some stuff
String data = "Waffles and pwnies";
// Notify the observers that something happened.
notifyObservers(data)
}
}
…and here is the simple observer interface.
public interface SimpleObserver {
void onEvent(String data);
}
This may seem a bit complex, but the benefit is that the Observable class doesn't need to know what exact other objects are "listening" to it (which is why observers are sometimes called listeners). It provides a clean separation of concerns between them both. The Observers need to register themselves to an observable.
The only "gotcha" that I can think of is that of a memory leak that this pattern may cause even in a memory managed environment such as Java. This is because of the "reference islands" between Observers and Observables which will confuse the garbage collector and not attempt to remove the objects from memory. It is always a good idea to remove unused observers.
Java doesn't have a dedicated concept of Event. It's implemented through APIs along the lines of Observable + Observer. As far as I know, there is no dedicated lambda-functer API in the Java specification.
Events are strictly container specific in Java, and the standard library merely provides a generalized interface (which is typically extended for specific requirements).
The only 'gotcha' regarding events that can arguably be considered in context of Java (in general) is in Swing containers (Component) and event dispatching. The swing framework is single-threaded and you are expected to not use the event dispatch thread (i.e. the call back) to do computationally intensive/high-latency work in the event listener.
When would you favour using a callback (i.e, passing in a Func or Action), as opposed to exposing and using an event?
UPDATE
What motivated this question was the following problem:
I have a ThingsHandler class, which
can be associated with a ThingEditor.
The ThingsHandler handles a list of
Things, knows their order, which one is 'current', when new
ones are added or deleted etc.
The ThingEditors can just modify a single
thing.
The ThingsHandler needs to alert
the ThingEditor when the user selects
a new Thing to edit, and the
ThingEditor needs to alert the
ThingsHandler when the user says
'done'.
What bothers me is having these two classes holding references to each other - though I guess that's inevitable - or binding to events in both directions. I wondered if using a callback in one direction was 'cleaner'.
I suspect there is a design pattern for this.
Though the other answers thus far seem reasonable, I would take a more philosophical tack.
A class is a mechanism that models a particular kind of thing in a particular domain. It is very easy when writing the internal details of a class to conflate the implementation details of the mechanism with the semantics being modeled. A brief example of what I mean:
class Giraffe : Mammal, IDisposable
{
public override void Eat(Food f) { ... }
public void Dispose() { ... }
}
Notice how we've conflated the real-world thing being modeled (a giraffe is a kind of mammal, a giraffe eats food) with the details of the implementation (an instance of Giraffe is an object which can be disposed of with the "using" statement). I guarantee that if you go to the zoo, you will never see a giraffe being disposed of with the using statement. We've mixed up the levels here, which is unfortunate.
I try to use events (and properties) as part of the semantic model and use callback methods (and fields) as part of the mechanism. I would make GaveBirth an event of Giraffe, since that is part of the model of real-world giraffe behaviour we're attempting to capture. If I had some mechanism, like, say I wanted to implement an inorder-walk tree traversal algorithm that walked the family tree of giraffes and called a method back on every one, then I'd say that this was clearly a mechanism and not part of the model, and make it a callback rather than try to shoehorn that into the event model.
I use callbacks in a few cases where I know it will only ever fire once, and the callback is specific to a single method call (rather than to an object instance) - for example, as the return part of an async method.
This is particularly true of static utility methods (since you don't have an instance, and static events are deadly when used carelessly, and to be avoided), but of course the other option is to create a class instance with an event instead.
Generally, I use a callback if it is required, whereas an event is used when it should be optional.
Don't expose an event if you're expecting there to always be something listening.
Consider the following:
public class MyClass_Event
{
public event EventHandler MakeMeDoWork;
public void DoWork()
{
if (MakeMeDoWork == null)
throw new Exception("Set the event MakeMeDoWork before calling this method.");
MakeMeDoWork(this, EventArgs.Empty);
}
}
versus:
public class MyClass_Callback
{
public void DoWork(EventHandler callback)
{
if (callback == null)
throw new ArgumentException("Set the callback.", "callback"); // better design
callback(this, EventArgs.Empty);
}
}
The code is almost the same as the callback can be passed as null, but at least the exception thrown can be more relevant.
Callbacks are good when one object wishes to receive a single notification (e.g. an Async data read runs and then calls you with the result).
Events are good for recurring notifications that can be received by an arbitrary number of listeners.
One example is when the callback should return something. E.g. (stupid example):
public int Sum(Func<int> callbackA, Func<int> callbackB) {
return callbackA() + callbackB();
}
public void UseSum() {
return sum(() => 10, () => 20);
}
In terms of OO design and class coupling there isn't great deal of difference between a callback interface and an event.
However, I prefer events where they are things the class needs to "shout about" to whoever is interested in listening (usually multiple things) and callbacks where a specific class has requested an async operation.
Whatever you use, use them consistently across the codebase!
I would use Func or Action when I am going to call the function once or use a Lambda expression.
Events can be registered more than once which sometimes is ideal. With a callback, one has to implement a registration system for the callbacks if you want multiple.
Well, I think they are same things. There're many different tech terms to name the same concepts or things in the different languages.
So, what do you mean "Callback" or "event handler"?
According to MSDN: Callback function is code within a managed application that helps an unmanaged DLL function complete a task.
And, MADN also gives us a introduction of the difference between them.click here
Callbacks are extensibility points that allow a framework to call back into user code through a delegate. These delegates are usually passed to the framework through a parameter of a method.
Events are a special case of callbacks that supports convenient and consistent syntax for supplying the delegate (an event handler). In addition, Visual Studio’s statement completion and designers provide help in using event-based APIs
Also, in some books, such as this book, the author seemed say the same thing with MSDN.
Therefore, in my opinion, you can't say use callbacks instead of events in the C#.
I've got the following (simplified):
interface IFindFilesObserver
{
void OnFoundFile(FileInfo fileInfo);
void OnFoundDirectory(DirectoryInfo directoryInfo);
}
class FindFiles
{
IFindFilesObserver _observer;
// ...
}
...and I'm conflicted. This is basically what I would have written in C++, but C# has events. Should I change the code to use events, or should I leave it alone?
What are the advantages or disadvantages of events over a traditional observer interface?
Consider an event to be a callback interface where the interface has only one method.
Only hook events you need
With events, you only need to implement handlers for events you're interested in handling. In the observer interface pattern, you'd have to implement all methods in the entire interface including implementing method bodies for notification types you don't actually care about handling. In your example, you always have to implement OnFoundDirectory and OnFoundFile, even if you only care about one of these events.
Less maintenance
Another good thing about events is you can add a new one to a particular class so that it will raise it, and you don't have to change every existing observer. Whereas if you want to add a new method to an interface, you have to go around every class that already implements that interface and implement the new method in all of them. With an event though, you only need to alter existing classes that actually want to do something in response to the new event you're adding.
The pattern is built into the language so everybody knows how to use it
Events are idiomatic, in that when you see an event, you know how to use it. With an observer interface, people often implement different ways of registering to receive notifications and hook up the observer.. with events though, once you've learnt how to register and use one (with the += operator), the rest are all the same.
Pros for interfaces
I haven't got many pros for interfaces. I guess they force someone to implement all methods in the interface. But, you can't really force somebody to implement all those methods correctly, so I don't think there's a lot of value on this.
Syntax
Some people don't like the way you have to declare a delegate type for each event. Also, standard event handlers in the .NET framework have these parameters: (object sender, EventArgs args). As sender doesn't specify a particular type, you have to down-cast if you want to use it. This often is fine in practice, it feels not quite right though because you're losing the protection of the static type system. But, if you implement your own events and don't follow the .NET framework convention on this, you can use the correct type so potential down-casting isn't required.
Hmm, events can be used to implement the Observer pattern. In fact, using events can be regarded as another implementation of the observer-pattern imho.
Events are harder to propagate through chain of objects, for example if you use FACADE pattern or delegate work to other class.
You need to be very careful with unsubscribing from events to allow object to be garbage collected.
Events are 2x time slower than simple function call, 3x slower if you do null check on every raise, and copy event delegate before null check and invocation to make it thread safe.
Also read MSDN about new (in 4.0) IObserver<T> interface.
Consider this example:
using System;
namespace Example
{
//Observer
public class SomeFacade
{
public void DoSomeWork(IObserver notificationObject)
{
Worker worker = new Worker(notificationObject);
worker.DoWork();
}
}
public class Worker
{
private readonly IObserver _notificationObject;
public Worker(IObserver notificationObject)
{
_notificationObject = notificationObject;
}
public void DoWork()
{
//...
_notificationObject.Progress(100);
_notificationObject.Done();
}
}
public interface IObserver
{
void Done();
void Progress(int amount);
}
//Events
public class SomeFacadeWithEvents
{
public event Action Done;
public event Action<int> Progress;
private void RaiseDone()
{
if (Done != null) Done();
}
private void RaiseProgress(int amount)
{
if (Progress != null) Progress(amount);
}
public void DoSomeWork()
{
WorkerWithEvents worker = new WorkerWithEvents();
worker.Done += RaiseDone;
worker.Progress += RaiseProgress;
worker.DoWork();
//Also we neede to unsubscribe...
worker.Done -= RaiseDone;
worker.Progress -= RaiseProgress;
}
}
public class WorkerWithEvents
{
public event Action Done;
public event Action<int> Progress;
public void DoWork()
{
//...
Progress(100);
Done();
}
}
}
Pros of an interface-solution:
If you add methods, existing observers needs to implement those methods. This means that you have less of a chance of forgetting to wire up existing observers to new functionality. You can of course implement them as empty methods which means you have the luxury of still doing nothing in response to certain "events". But you won't so easily forget.
If you use explicit implementation, you'll also get compiler errors the other way, if you remove or change existing interfaces, then observers implementing them will stop compiling.
Cons:
More thought has to go into planning, since a change in the observer interface might enforce changes all over your solution, which might require different planning. Since a simple event is optional, little or no other code has to change unless that other code should react to the event.
Some further benefits of events.
You get proper multicast behaviour for free.
If you change the subscribers of an event in response to that event the behaviour is well defined
They can be introspected (reflected) easily and consistently
Tool chain support for events (simply because they are the idiom in .net)
You get the option to use the asynchronous apis it provides
You can achieve all of these (except the tool chain) yourself but it's surprisingly hard. For example:
If you use a member variable like a List<> to store the list of observers.
If you use foreach to iterate over it then any attempt to add or remove a subscriber within one of the OnFoo() method callbacks will trigger an exception unless you write further code to deal with it cleanly.
The best way to decide is this: which one suits the situation better. That might sound like a silly or unhelpful answer, but I don't think you should regard one or the other as the "proper" solution.
We can throw a hundred tips at you. Events are best when the observer is expected to listen for arbitrary events. An interface is best when the observer is expected to listed to all of a given set of events. Events are best when dealing with GUI apps. Interfaces consume less memory (a single pointer for multiple events). Yadda yadda yadda. A bulleted list of pros and cons is something to think about, but not a definitive answer. What you really need to do is try both of them in actual applications and get a good feel for them. Then you can choose the one that suits the situation better. Learn form doing.
If you have to use a single defining question, then ask yourself which better describes your situation: A set of loosely related events any of which may be used or ignored, or a set of closely related events which will all generally need to be handled by one observer. But then, I'm just describing the event model and interface model, so I'm back at square one: which one suits the situation better?
Pros are that events are more 'dot-netty'. If you are designing non-visual components that can be dropped onto a form, you can hook them up using the designer.
Cons are that an event only signifies a single event - you need a separate event for each 'thing' that you want to notify the observer about. This doesn't really have much practical impact except that each observed object would need to hold a reference for every observer for every event, bloating memory in the case where there are lots of observed objects (one of the reasons they made a different way of managing the observer/observable relationship in WPF).
In your case I'd argue it doesn't make much difference. If the observer would typically be interested in all those events, use an observer interface rather than separate events.
I prefer an event base solution for the following reasons
It reduces the cost of entry. It's much easier to say "+= new EventHandler" than to implement a full fledged interface.
It reduces maintenance costs. If you add a new event into your class that's all that needs to be done. If you add a new event to an interface you must update every single consumer in your code base. Or define an entirely new interface which over time gets annoying to consumers "Do I implement IRandomEvent2 or IRandomEvent5?"
Events allow for handlers to be non-class based (ie a static method somewhere). There is no functional reason to force all event handlers to be an instance member
Grouping a bunch of events into an interface is making an assumption about how the events are used (and it's just that, an assumption)
Interfaces offer no real advantage over a raw event.
Java has language support for anonymous interfaces, so callback interfaces are the thing to use in Java.
C# has support for anonymous delegates - lambdas - and so events are the thing to use in C#.
A benefit of interfaces is that they are easier to apply decorators to. The standard example:
subject.RegisterObserver(new LoggingObserver(myRealObserver));
compared to:
subject.AnEvent += (sender, args) => { LogTheEvent(); realEventHandler(sender, args); };
(I'm a big fan of the decorator pattern).
If your objects will need to be serialized in some way that retains references such as with NetDataContractSerializer or perhaps protobuf events will not be able to cross the serialization boundary. Since observer pattern relies on nothing more than just object references, it can work with this type of serialization with no problem if that is what is desired.
Ex. You have a bunch of business objects that link to each other bidirectionally that you need to pass to a web service.