Design Patterns - Observer/Event Pattern
Yesterday I described the Observer Pattern and mentioned that the .NET CLR provides this functionality through events and delegates.
Let's have a look on how to implement this right now.
First of all, we can get rid of our ISubject and IObserver interfaces. And we'll replace it by a push notification mechanism.
Push, because we'll pass the required information along to the observers when notifying them, as opposed to pull, where the observers had to extract it themselves from the subject.
Since we'll be pushing out the information, we need a custom class defining which information is interesting. We'll create this by inheriting from the EventArgs class, by doing this it will be very easy to set up an event in the next step.
As you can see, this is a very small class, with a descriptive name, containing the new location of our unit.
You can't see it on this diagram, but the NewLocation property only has a public getter, and a private setter, since our observers will only have to extract data from this class.
So, we got our small information holding class, now it's time to change our GameUnit class to get rid of all the logic of maintaining a list of observers and subscription logic.
We'll replace the ISubject logic by an event of the type EventHandler<PositionChangedEventArgs>. By doing this, we expose an event (PositionChanged) to our observers upon which they can subscribe themselves whenever they want as well as unsubscribe when needed.
Note that this event is strongly typed, containing a strongly typed information set, making it easy for our observers to get the information they need.
Using this method, we can have a set of EventArgs classes as small data holders, after which subjects can expose events using those custom EventArgs to the outside world, making sending out notifications very easy.
Observers on their side can easily subscribe to any of the events exposed by using a single line of code, and perform their logic (_PositionChanged methods) whenever they get a notification.
Have a look at the the uploaded solution to see the exact syntax of this method. We're using delegates with generics, the += operator and throwing and handling events.
Again, if you have any questions, feel free to leave them behind.
Some additional information on the Observer/Event pattern: