Codiwan.com

The blog for Design Patterns, Linux, HA and Myself!

Observer Pattern With Real World Example In Java

Observer Pattern or Observer Design Pattern: Learn Observer Design Pattern in detail from a Real World Example by creating a Magazine's Subscription System

In this tutorial we’ll be looking into Observer Design Pattern. We will learn about the Observer Design Pattern by creating a subscription system for a Magazine Company. There will be some design problems that we’ll find, and then we’ll apply the Observer Design Pattern to solve those problems.

Observer Pattern

This magazine company, ReadDigest, has a complex algorithm of creating the weekly article. It wants to send the newly generated articles to it’s subscribers but it doesn’t know how to do it.

This is the problem that we’ve to solve.

It has provided us the API that is called whenever new content is generated.

Note: Make sure to go through the code comments as well. It’ll help you understand the concept better.

abstract class ReadDigest {
    
    // The title of the current edition
    private String currentTitle;

    // Some information about the current edition
    private String moreInfo;

    // This method is called whenever there is some new content available
    abstract void onNewContent();

    // This method generates the new content for the magazine
    // and calls onNewContent() for broadcasting the info.
    void generateContent() {
        // some complex technique to create content and it's code is hidden from the mere mortals
        :
        :
        :
        // finally, call the onNewContent() method
        this.onNewContent();
    }
}

Currently, it has 3 subscribers, a Race car Driver, a Newspaper Man and a Movie Director.

The class for the Race car driver:

class RaceCarDriver {

    void receiveNewContent(String title, String moreContent) {
        System.out.println("RaceCarDriver Receives...");
        System.out.println(title);
        System.out.println(moreContent);
    }
}

The class for the Newspaper man:

class NewsPaperMan {

    void receiveNewArticle(String title, String moreContent) {
        System.out.println("NewsPaperMan Receives...");
        System.out.println(title);
        System.out.println(moreContent);
    }
}

And, the class for the Movie director:

class MovieDirector {

    void receiveNewMediaStory(String title, String moreContent) {
        System.out.println("MovieDirector Receives...");
        System.out.println(title);
        System.out.println(moreContent);
    }
}

If you read the classes of the subscribers of the Magazine company then you’ll find that each of them have a method to get the latest information from the Read Digest magazine company. So, in our solution all we have to do is to call these methods of the subscribers whenever new content is generated.

The first solution that comes into our mind is to just hook our subscription algorithm into it, i.e., to notify the subscribers one by one whenever new content is published. The method, onNewContent(), looks like the best place to add that code.

class ReadDigestWithSubscription extends ReadDigest {

    private RaceCarDriver raceCarDriver;
    private NewsPaperMan newsPaperMan;
    private MovieDirector movieDirector;

    ReadDigestWithSubscription(RaceCarDriver raceCarDriver, NewsPaperMan newsPaperMan, MovieDirector movieDirector) {
        this.movieDirector = movieDirector;
        this.raceCarDriver = raceCarDriver;
        this.newsPaperMan = newsPaperMan;
    }

    void onNewContent() {
        raceCarDriver.receiveNewContent(this.getCurrentTitle(), this.getMoreInfo());
        newsPaperMan.receiveNewArticle(this.getCurrentTitle(), this.getMoreInfo());
        movieDirector.receiveNewMediaStory(this.getCurrentTitle(), this.getMoreInfo());
    }
}

And, we are able to successfully notify all the customers of ReadDigest whenever there’s some new info available and because of this more and more customers want to become the subscribers of the magazine.

So, how to add more subscribers? By adding more objects inside the ReadDigestWithSubscription class? By adding more arguments in the constructor of the ReadDigestWithSubscription? By adding one new line for one new subscriber into the method onNewContent()?

No.

While we’re able to solve the problem but there are a few mistakes that we cannot ignore. Let’s look at them:

Now that we know the mistakes. Let’s try to fix them by using Observer Design Pattern.

In observable design pattern there are two types of classes:

The Observable keeps a list of Observers and notifies them whenever the it’s state changes.

Looks like it is a right fit for us!

The Read Digest Magazine CompanyObservable keeps a list of SubscribersObservers and notifies them whenever the it’s contentstate changes.

The Read Digest company becomes the Observable and the Subscribers become the Observers. We’ll be using Java’s own Observer classes. But you can create your own if you want.

The ReadDigest class will now extend java.util.Observable and it will inherit following three methods that we’ll require:

class ReadDigest extends java.util.Observable {

    private String currentTitle;

    private String moreInfo;

    void generateContent() {
        // some complex technique to create content and it's code is hidden from the mere mortals
        :
        :
        :
        // finally, set the status of the Read Digest Changed
        // and call the notifyObservers
        this.setChanged();
        this.notifyObservers();
    }
}

The classes RaceCarDriver, NewsPaperMan, and MovieDirector will now extend java.util.Observer and it will inherit following one methods that we’ll require:

The new version of RaceCarDriver

class RaceCarDriver implements java.util.Observer {

    private void receiveNewContent(String title, String moreContent) {
        System.out.println("RaceCarDriver Receives...");
        System.out.println(title);
        System.out.println(moreContent);
    }

    @Override
    public void update(Observable o, Object arg) {
        if (o instanceof ReadDigest) {
            ReadDigest readDigest = (ReadDigest) o;
            this.receiveNewContent(readDigest.getCurrentTitle(), readDigest.getMoreInfo());
        }
    }
}

Using this new implementation we’ve made sure that the Race Car Driver(or the Observers) and the Magazine Company( or the observables are loosely coupled). All they about them is that they are either an Observer or an Observable, nothing more than that.

And because all the observers are of same type now, it will be easy to add/update or delete them.

This the UML class diagram:

UML Class Diagram

Finally the definition from the 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.

I’ve created these tutorials after learning Design Patterns from this book Head First Design Patterns (A Brain Friendly Guide).

Loading Comments... Disqus Loader
comments powered by Disqus