Behavioural - Observer Pattern

Observable maintains a list of Observers and notifies them one when there is any change in its state.

Every time the YouTube channel (the Observable) uploads a new video, it wants to make sure its subscribers (the Observers) know about it. If someone decides they don’t want updates anymore, they quietly unsubscribe, and the channel won't send any notifications.

Low Level Design

Observer Design Pattern

Let's discuss the above diagram , considering Youtube Channel and Subscribers as an example.

Requirement

  • Subscriber should be able to subscribe to Channel

  • Whenever Channel uploads a video, channel should notify its subscribers

Implementation

We will implement above diagram considering

Observable = Channel

Observer = Subscriber

The interfaces

public interface Observable { // channel

	void addSubscriber(Subscriber subscriber);

	void removeSubscriber(Subscriber subscriber);

	void notifySubscribers();

	void upload(Video video);
}
public interface Subscriber {
	void update();
}

Concrete Classes

Let's first create a Video class which will be uploaded by Channel.

@Data
@AllArgsConstructor
public class Video {
	String name;
	String description;
}

I have used Lombok library annotations @Data for boilerplate getter/setter methods and @AllArgsConstructor for parametrized constructor.

Now let's create concrete obervable and observer classes. In our example, we will create ChannelObservable and ChannelSubscriber concrete classes.

public class ChannelObservable implements Observable {
	//Has-A
	private List<ChannelSubscriber> subs = new ArrayList<>();

	private Video video;

	@Override
	public void addSubscriber(ChannelSubscriber subscriber) {
		subs.add(subscriber);
	}

	@Override
	public void removeSubscriber(ChannelSubscriber subscriber) {
		subs.remove(subscriber);
	}

	@Override
	public void notifySubscribers() {
		for (ChannelSubscriber sub : subs) {
			sub.update();
		}
	}

	@Override
	public void upload(Video video) {
		this.video = video;
		notifySubscribers();
	}

	public String getTitle() { // for state change
		return video.getName();
	}
}
public class ChannelSubscriber implements Subscriber{
	private String subscriberName;

	//Has-A
	private ChannelObservable channel;

	public ChannelSubscriber(String name, ChannelObservable observable) {
		this.subscriberName = name;
		this.channel = observable;
	}

	@Override
	public void update() {
		System.out.println("Hey " + subscriberName + ", " +
			"Video Uploaded about " + this.channel.getTitle());
	}
}

Now it's time to create our app called Youtube 🎉

public class Youtube {

	public static void main(String[] args) {
		ChannelObservable channel = new ChannelObservable();

		ChannelSubscriber s1 = new ChannelSubscriber("X", channel);
		ChannelSubscriber s2 = new ChannelSubscriber("Y", channel);

		channel.addSubscriber(s1);
		channel.addSubscriber(s2);

		channel.upload(new Video("Design Pattern in Java",
			"All about design patterns"));

		channel.removeSubscriber(s2);

		channel.upload(new Video("Java8 functional programming",
			"All about functional Programming"));
	}
}

Output

Hey X, Video Uploaded about Design Pattern in Java
Hey Y, Video Uploaded about Design Pattern in Java
Hey X, Video Uploaded about Java8 functional programming

Hope you have understood the pattern in a simple manner

Last updated

Was this helpful?