What is it?
Real world
- Social media
- When a person updates his status – all his followers gets the notification
- A follower can follow or unfollow another person at any point of time
- Once unfollowed, person will not get the notifications from subject in future
Real world diagram
- One-to-many dependencies between objects
- Also known as publish-subscribe pattern
- There are many observers (subscriber objects) that are observing a particular subject (publisher object)
- Observers register themselves to a subject to get a notification when there is a change made inside that subject
Sequence diagram
Architecture
Coding example
Subject and concreteSubject
- Subject – interface or abstract class defining the operations for attaching and de-attaching observers to the subject
- ConcreteSubject – concrete Subject class. It maintain the state of the object and when a change in the state occurs it notifies the attached Observers
// Subject public interface Subject { public void attach(Observer o); public void detach(Observer o); public void notifyUpdate(Message m); }
// MessagePublisher.java import java.util.ArrayList; import java.util.List; public class MessagePublisher implements Subject { private List<Observer> observers = new ArrayList<>(); @Override public void attach(Observer o) { observers.add(o); } @Override public void detach(Observer o) { observers.remove(o); } @Override public void notifyUpdate(Message m) { for(Observer o: observers) { o.update(m); } } }
Observer and ConcreteObservers
- Observer – interface or abstract class defining the operations to be used to notify this object
- ConcreteObserver – concrete Observer implementations
// Observer.java public interface Observer { public void update(Message m); }
// MessageSubscriberOne.java public class MessageSubscriberOne implements Observer { @Override public void update(Message m) { System.out.println("MessageSubscriberOne :: " + m.getMessageContent()); } } // MessageSubscriberTwo.java public class MessageSubscriberTwo implements Observer { @Override public void update(Message m) { System.out.println("MessageSubscriberTwo :: " + m.getMessageContent()); } } // MessageSubscriberThree.java public class MessageSubscriberThree implements Observer { @Override public void update(Message m) { System.out.println("MessageSubscriberThree :: " + m.getMessageContent()); } }
State object
This must be an immutable object so that no class can modify it’s content by mistake
// Message.java public class Message { final String messageContent; public Message (String m) { this.messageContent = m; } public String getMessageContent() { return messageContent; } }
Test communication between publisher and subscribers
// Main.java public class Main { public static void main(String[] args) { MessageSubscriberOne s1 = new MessageSubscriberOne(); MessageSubscriberTwo s2 = new MessageSubscriberTwo(); MessageSubscriberThree s3 = new MessageSubscriberThree(); MessagePublisher p = new MessagePublisher(); p.attach(s1); p.attach(s2); p.notifyUpdate(new Message("First Message")); //s1 and s2 will receive the update p.detach(s1); p.attach(s3); p.notifyUpdate(new Message("Second Message")); //s2 and s3 will receive the update } }
// Console output MessageSubscriberOne :: First Message MessageSubscriberTwo :: First Message MessageSubscriberTwo :: Second Message MessageSubscriberThree :: Second Message
Leave a Reply