Lately, I’ve been trying to become more familiar with design patterns. One thing I’ve realized along the way is that it’s not easy to recognize where a specific pattern might be useful. It usually comes down to having that light bulb moment where you suddenly say to yourself “Hey! This might be a good place to use a certain design pattern.”
Define the problem.
With the rise of frameworks like React, we often hear about ‘application/component state.’ When the state is updated, components will re-render accordingly. In React, components are just a representation of what the user interface should look like.
So, let’s define the problem we are trying to solve: we need to be able to update multiple page elements when our application state changes.
In this post, we will build out a little app that allows you to add users to a list. This app will use state; so we will use the observer pattern to notify the elements that need updated when that state changes.
What is application state?
For example, maybe you have a small app that displays a list of items it retrieves from an external API. When the app loads, it makes sense to make the API call once and store the data in app state. The app could then render based on changes to its state.
The Observer Pattern
According to Wikipedia:
The observer pattern is a software design pattern in which an object, called the subject, maintains a list of its dependents, called observers, and notifies them automatically of any state changes, usually by calling one of their methods.
The observer pattern defines a one-to-many relationship. When one object updates, it notifies many other objects that it has been updated.
It’s easy to get tripped up with the subject and observer terms used in the definition above. It took me a while to wrap my head around it.
Here is a brief explanation for each:
- subject – This is the object that will send out a notification to all of the ‘observers’ who want/need to know that the subject was updated. In our case, the subject will be the application state object.
- observers – These are the objects that want to know when the subject has changed. In our case, these will be the page elements that need to update when the application state changes.
When implementing design patterns, there is often a contract that needs to be followed in order for the implementation to be correct.
What do I mean by contract? Well, in a more object-oriented language like PHP, there may be specific interfaces that the subject and observer classes need to implement. Those interfaces would in turn force any class that implements them to have the methods specified in the interface.
Here is a basic class diagram for visual reference:
The purpose of the subject class is to maintain a list of observers that it needs to notify when it is updated. It will need the ability to add or remove observers as well.
Here is a brief explanation for the properties and methods that are required on the Subject class:
- observers – This class property holds an array of observers.
- addObserver() – Will push an observer on to the observer’s array
- removeObserver() – Will remove an observer from the observer’s array
- notify() – Will notify all observers that a change has happened
The purpose of the observer class is to implement an update() method that will be called by the subjects notify() method. In our case, the concrete implementation of the update() method will re-render the element.
If you’re like me, talking theory is cool, but a concrete example is what really helps me understand what is going on.
I’ve created a very simple app that does two things:
- Allows users to be added to a list
- Updates a user count indicator when a user is added to the list
The basic flow of the app goes like this: when the new user is submitted via the input, a state change is triggered. Because the state has changed, both the list and user counter are automatically re-rendered because they are observing the state object.
Let’s walk through a few of the key files for further explanation and context.
The subject class is one part of the observable pattern. It’s the object that will notify all of the observers that it has changed in some way.
Take note that we have an observers property plus the addObserver, removeObserver, and notify methods.
The observer class is the second part of the observable pattern. It’s that object that gets notified when something in the subject class has updated.
The implementation for the update function is blank in this class. We will leave the implementation details to the concrete class.
The state class will be the application state for our app. It extends the subject class, so in turn, it inherits all of the functions on the subject class.
On instantiation, the constructor sets the state to an empty object. The get() method just returns the state. The update() method is a bit more interesting. It will update the state and then run the notify() method passing along the updated state. This allows any observers to have access to the updated state.
In total, we have three components in the app. We’ll just look at the list component because the others are very similar.
The list component extends the observable class. This means that it wants to know when the application state (subject) has changed. Notice how we override the update method with an actual implementation that re-renders the component.
Below is a link to the working demo of the app. Check it out and make magic happen by adding a few users.
Feel free to hit me up in the comments below if you have any questions or comments.