One of my most commonly used design patterns is the Observer Pattern and for good reasons. At its core, it allows you to program easier and worry less about how objects will get updated. For example, when programming using the MVC framework, you often want the views to be notified when the model’s state changes. React uses this same pattern under the hood to update components when the state changes. React hooks are also another cool way to use the pattern. With it being used so frequently in multiple programming languages/frameworks, I thought it would be beneficial to do a quick recap of what the pattern is and how it works!
“Observer Pattern Intent — Define a one-to-many dependency between objects so that when one object changes state, all its dependents are notified and updated automatically.” — Design Patterns: Elements of Reusable Object-Oriented Software
Why is the Observer Pattern Important?
This pattern is critical to building robust applications because it decouples the implementation of the Subject from the Observer. This is pivotal because without this, you could have a huge dependency tree that would often have to violate encapsulation. The benefit in the future is that you can reuse the subjects without having to reuse the observers, and vice versa. You can also add observers without having to modify the subject or mess with any of the other observers. This plug and play attribute is highly desirable when trying to build production applications.
Let’s walk through a quick example of how to practically use the Observer pattern in c#. This is most commonly done by handling and raising events. .Net events follow the delegate model and it enables an Observer to register and receive notifications from a Subject when an event is fired. Let’s walk through an example of a Clock.
Suppose you wanted to build a Clock app with some Alarm functionality. You could implement a Clock.cs that handles when the alarm time is reached.
The benefit to this is that in your main program, you can simply specify the time you want the alarm to go off, and then wait for the event to be raised.
Notice that after the event is raised in ‘OnAlarmRaised’ I unsubscribe from the event. This is considered a good practice as you never know when events could be fired, and forgetting to unsubscribe could lead to memory leaks.
I realize that this example deviates from the typical example of the observer pattern, but it goes to show that the pattern isn’t always one for one with the book definition. I think that the example I showed is a cleaner example that requires less code overall 🙂
The observer pattern might be confusing the first couple of times you set out to use it, but will provide great advantages down the road. Give it a try in your next project!