Note: This is part of an ongoing series introducing patterns at the Tampa C# Meetup.
No introduction to patterns is complete without the ubiquitous explanation of why we need patterns. Rather then re-invent this wheel, yet again, I will reference others and refer you to a couple books.
In software engineering, a design pattern is a general reusable solution to a commonly occurring problem in software design. A design pattern is not a finished design that can be transformed directly into code. It is a description or template for how to solve a problem that can be used in many different situations. – Design Pattern @ Wikipedia
The Design Patterns book, commonly referred to as the Gang of Four because of the four authors, is the baseline must-have book in this space. However, I find myself using the Head First Design Patterns more often due to its simpler explanations and easy to understand graphical depictions of the patterns.
The Observer Patten addresses the usage scenario when one entity needs to be aware of a change in the state of another entity.
Using this pattern requires three things.
- One or more observers must register interest with the observed
- The observed must notify the list of observers upon state change
- One or more observers must be able to unregister their interest with the observed
This is most frequent usage of this pattern in .NET, and most people that use it don’t even realize that they are using the observable pattern. Enough chatter, lets see some code.
Base Class Library (BCL) Interfaces
The .NET BCL provides a pair of interfaces to support the observer pattern. Not surprisingly, they are called
IObserver<>. This is a bit more work to setup then using events, but they do essentially the same thing. Lets look at some code.
One of the beauties of patterns is that they are implementation agnostic. I have shown two ways for you to implement the observer pattern in your own code. The eventing model is easier to use and feels more natural to those used to forms based development, but you give some control over the management of the subscription and event firing in doing so. There are ways around it, but by the time your done, your code may look more similar to the interface approach. The interface approach does not offer any of the plumbing to support you, but it gives you the freedom to implement the solution differently. One classic example is dealing with multi-threaded scenarios, such as registering subscribers from different threads, or publishing subscribers across multiple threads.
I am just skimming the surface of patterns, and the observer pattern specifically. Over the course of these micro-posts, I will cover more patterns, and eventually move on to enterprise patterns. Of course, you can just drop into the Tampa C# Meetup as I present these posts for our Patterns 101 segment.