I have previously written a few posts about delegates, .NET Events, Events Args to show that similar to real-world events, we can use this concept in our code and how useful they are in certain scenarios. This post will see that those types are a good candidate for implementing the observer pattern without doing anything extra. We will learn some terminologies and see a working example as well.
If you are new to .NET Events, I will suggest reading my previous posts on the topic, and then discussed in this post will be easier to follow. So let’s talk about observer pattern:
The observer pattern is simply a publish/subscribe relationship.
- The publisher is also referred to as the subject that we want to watch for a state change.
- Then we have one or more Subscribers, also referred to as Observers. These are the dependent objects that will be notified when the state changes.
On Twitter, Follow capability allows up to setup an observer relationship whenever I follow someone on Twitter, whenever that person’s state changes (by adding a tweet), I notified it. Not only me, everyone who is the follower gets notified.
It turns out that if you’ve used an event handler in .NET, you have used an observer pattern.
Consider Observers When?
- One object is dependent on the changes in another object.
- Changing in one Object requires changes to many others (other objects are monitoring one object).
- When changes to an object should allow notification to others without any knowledge of them.
Intent and Structure
- Creates a separation b/w the subject & observer
- Allow multiple observers to react to changes to a single object.
- The subject provides a way to Register, Un-Register, and Notify.
- Observer provides a way to Update.
Before we dive into the observer pattern, let’s see the current code. I created an Account class with two methods Deposit and Withdrew. Account class also has a balance property, which changes when we either deposit or withdraw the amount. Find below the implementation of Account.
Next, I have the following code in the Main method:
Output when running this code:
Our application code is doing some basic work, and it is a very typical C# code.
Let’s imagine that we have new requirements as follows:
- Send Email whenever balance changes.
- Log balance changes
As you can see that these requirements fit the need for an observer pattern. If we consider our Account class as a subject, we can raise notifications whenever balance changes. On the other end, Logger and Emailer can be considered observers interested in this balance change information for their operations.
The event, EventHandlers, and Custom EventArgs
We can use built-in .NET Types to implement observer pattern easily if you are new to these concepts. You can read about those in my previous posts on the same topic.
To raise notifications from the Account class, I am using built-in EventHandler<T> from .NET. Then I updated the Deposit and Withdrew method to raise the events along with event-data.
I could have put the event raise code in the property-setter of Balance as well (to avoid duplicated code, but for now, it is ok). So our Account class is now a subject or source of the event, or you can call it a publisher.
Here is the custom EventArgs class. This class is used to pass data when an event is raised.
Now, on the receiving end, I added two classes to represent the subject’s observers (or consumers). Here is the code:
Notice that event wiring or registration is being set up in the constructor of these classes. The rest of the code is straightforward and currently writing to console to simulate the operation.
So, now we have our subject, which raises an event (along with event-data) when balance changes, and then two observers are setup to listen for these events. With all this code in place, let’s update the Main method to see all this in action. Here is the updated code for the Main method:
Now, when I run the application. The following output shows that events are fired from the subject, and then observers are notified and processing those events.
Now, I will call deposit and withdraw methods multiple times to see the results:
Here is the output:
In this post, we saw one implementation of the observer pattern, which uses built-in .NET types. We learned a few terminologies, e.g., what is subject, what is observed, and learn that those are sometimes called publishers, subscribers, consumers, etc. If you have some comments or questions, feel free to ask. You can access the code on this URL. Till next time, Happy Coding.