Use cases
Imagine a scenario where you have a platform where users can create posts (like this one), and you received a new requirement so when a post is liked or disliked depending on how many likes it reiceived the post has to be monetized. The inicial solution is go where the post is liked/disliked and place an if like this:
if(post.likeCount > X){ callMonetization(post);}
Simple, now imagine that another requirement comes to you, saying that when any post is liked or disliked it should have an addtional log for compliance. So there you go place another if or inject another dependency on client code just to log the interesting part, this way you can end up with multiple if statement anytime you need to handle a new requirement, or having your code with multiple responsabilities/dependencies for each new requirement you have. Both scenarios are not good and observer design pattern can help us handle that.
Just for note the pattern is also known by other names like 'pub/sub'.
So let's create some code that implements the observer pattern.
This pattern uses an interface(observer) with methods that will be called on the observers (concrete implementation). First let's look at the arquitecture for a solution where we implemented a log requirement, a database save requirement, a notification requirement and a message queeu requirement(to focus on the pattern the specifics of those implementations were abstracted).
On that arquitecture we have a post entity, that have an author(person), an id, etc..
the observer interface and some pseudo concrete implementation, the post manager that will act as a proxy to our post like or dislike events calling the concret observers, the usecases that call manager's appropriate methods when invoked in client code, and offcourse there is the client code.
That said lets implement it in java:
the post entity
the observer interface
the post manager
the observer's implementation
and finally our client code:
so in client code we have a post manager used to add the observers (addObserver method), 2 usecases (like and dislike), people (one that create a post, and others that interact with it) and a method to create a fake id.
Executing the main method we'll see the following print statements (simplicity):
so that's it, whenever you want to react over some entity event like a post like/dislike, customer's transactions like withdraw, reimbursement, deposit, ect all you need to do is create another implementation of the observer interface, add it to the observers list in the manager and wait so your new observer will get called whenever an event occurs and you can use that call to handle your requirements.
Much better than inject not related code anywhere, don't you agreee?