Introduction
Observer Pattern is one of the behavioral design pattern. Observer design pattern is useful when you are interested in the state of an object and want to get notified whenever there is any change. The object that watch on the state of another object are called Observer and the object that is being watched is called Subject. The Observer Pattern defines a one to many dependency between objects so that one object changes state, all of its dependents are notified and updated automatically. One to many dependency is between Subject(One) and Observer(Many). Observers themselves don’t have access to data, they are dependent on Subject to provide them data.
The observer pattern exemplifies the design principle of loose coupling. This principle tells us to strive for loosely coupled designs between objects that interact. Loosely coupled objects don’t know a lot about each other, which makes them loosely coupled. Loose coupling helps to keep our design more flexible.
Intent
- Define a one-to-many dependency between objects so that when one object changes state, all its dependents are notified and updated automatically.
- Encapsulate the core (or common or engine) components in a Subject abstraction, and the variable (or optional or user interface) components in an Observer hierarchy.
Implementation
Observable (Subject) is interface or abstract class defining the operations for attaching and de-attaching observers to the client. ConcreteObservable maintain the state of the object and when a change in the state occurs it notifies the attached Observers. Observer interface define the operations to be used to notify this object.
Example
public interface Subject { // Methods to register and unregister observers public void register(Observer obj); public void unregister(Observer obj); // Method to notify observers of change public void notifyObservers(); //method to get updates from subject public Object getUpdate(Observer obj); } public interface Observer { // Method to update the observer, used by subject public void update(); } public class MyTopic implements Subject { private List<Observer> observers; private String message; public MyTopic(){ this.observers=new ArrayList<>(); } @Override public void register(Observer obj) { observers.add(obj); } @Override public void unregister(Observer obj) { observers.remove(obj); } @Override public void notifyObservers() { for (Observer obj : observers) { obj.update(); } } @Override public Object getUpdate(Observer obj) { return this.message; } // Method to post message to the topic public void postMessage(String msg){ this.message=msg; notifyObservers(); } } public class MyTopicSubscriber implements Observer { private String name; public MyTopicSubscriber(String nm){ this.name=nm; } @Override public void update() { String msg = (String) topic.getUpdate(this); System.out.println("Consuming message::" + msg); } } public class ObserverPatternTest { public static void main(String[] args) { // Create subject MyTopic topic = new MyTopic(); // Create observers Observer obj1 = new MyTopicSubscriber("Obj1"); Observer obj2 = new MyTopicSubscriber("Obj2"); // Register observers to the subject topic.register(obj1); topic.register(obj2); // Send message to subject topic.postMessage("New Message"); } }
Observer Pattern and Loose Coupling
Observable pattern helps make our design loosely coupled. Subjects and observers interact, which makes them coupled, but they really don’t know a lot about each other, which makes them loosely coupled.
- If you look at the subject, the subject knows only that the observer implements a certain interface. It doesn’t need to know the concrete class of the observer.
- Subject doesn’t know any details of the observer. All the subject knows is that it has a list of objects that implement the observable interface. And it uses that list to notify those observers when something changes.
- The observers are free to add themselves to the list at any time, they can also remove themselves, or even be replaced by another observer at any time. The subject just doesn’t care. All it does is maintain a list and notify the objects on that list as necessary.
- If we ever want to add a new type of observer, we can do that without ever touching the code of the subject. As long as the observer implements the observable interface, it can participate and get notified.
Any changes we make to the subject or the observers never affect the other. That’s true loose coupling.