Observer Design Pattern

Observer pattern is a behavioral design pattern where a collection of objects called observers listens for the state change of another object called subject. Observer pattern defines a one-to-many relationship between the subject and one or more of observers. The subject object maintains a list of its observer objects, and notifies those observers automatically if there are any state changes for the subject, usually by calling one method of the observer.

Observers can be added or removed from the list of observers in the subject. Observers should be able to register and unregister themselves with the Subject. The changes in the state of the subject may be passed to the observer. The subject may push its state data to the observer while calling the observer’s method to notify about the change, or the observer may later pull the subject’s state data from the subject after the notification.  

 

Relationships to design principles

Observer pattern is primarily based on the OO principle of low coupling. Subject and observers are loosely couples with each other. Only thing the client knows about the observer is the Observer interface. We can add or remove observers any time without any change the subject. We can reuse or change either subjects or observers independently of each other.   

 

Implementation components

  1. Subject (interface or abstract class)

  2. Concrete Subject

  3. Observer (interface or abstract class)

  4. Concrete Observer

 

Examples

The observer pattern is compared to newspaper subscription by the Head First design patterns book. You subscribe to a particular publisher and every time there is a new edition, it gets delivered to you. You may unsubscribe any time and the publisher stop delivering it to you.

A producer consumer problem can also be considered as an example of the observer pattern. Both producers and consumers will be listening to a common queue (subject). When data is available it will notify the consumers (observers). Similarly when the queue is full, the producers will wait and when space is available, it will notify the producers (observers).

Observer pattern is also one of the most heavily used patterns in the JDK; it is used in Swing and also in other places such as javabeans (PropertyChangeListener interface) and RMI.

 

Drawbacks and workaround

The observer pattern can cause memory leaks, known as the lapsed listener problem, because in basic implementation it requires both explicit registration and explicit deregistration, because the subject holds strong references to the observers, keeping them alive.

This memory leak problem can be prevented by using weak references; the subject may hold weak references to the observers.

 

Java’s built in support of observer pattern

Java provides a class Observable and an interface Observer, that together provide some built in support for the observer pattern. An Observable object and can have one or more observers (who implement Observer interface) added to it. After an Observable instance changes, an application calling the Observable's notifyObservers method causes all of its observers to be notified of the change by a call to Observer’s update method. Your subject in the observer pattern needs to extend the Observable class.

Methods of the Observable class are:

  • void addObserver(Observer o)
  • protected void clearChanged()
  • int countObservers()
  • void deleteObserver(Observer o)
  • void deleteObservers()
  • boolean hasChanged()
  • void notifyObservers()
  • void notifyObservers(Object arg)
  • protected void setChanged()

 

Only method of the Observer interface is:

  • void update(Observable o, Object arg)

 

You need to call the Observable class’s setChanged() to indicate that a change has happened and then call one of the two notifyObservers methods to notify the observers about the change. If the notifyObservers method is called without calling setChanged(), the observers will not be notified. The clearChanged() method set the changed state back to false.

If you call the notifyObservers method that has an object argument, this object argument will be passed as the second argument of the update method of the Observer interface. If you call the notifyObservers method that does not take any arguments, the update method of the Observer will be passed with a null for the second argument. Thus the notifyObservers method that has an object argument pushes data to the observer, whereas the notifyObservers method that does not take any arguments does not push any data and observers will have to pull data using the getter methods of your subject class (the class that extended Observable class).

The order in which notifications will be delivered is unspecified. The default implementation provided in the Observable class will notify Observers in the order in which they were registered, but subclasses may change this order, use no guaranteed order, deliver notifications on separate threads, or may guarantee that their subclass follows this order, as they choose. Also note that this notification mechanism is has nothing to do with threads and is completely separate from the wait and notify mechanism of class Object.

One of the biggest disadvantages of the Observable class in JDK is the lack of a parent interface. This is against the Open Closed Principle (OCP). Another disadvantage is that the Observable class has made the setChanged() and clearChanged() methods as protected. Hence we cannot call them unless you have sub-classed Observable. This violates another principle, prefer composition over inheritance. Therefore it might be a good idea to write your own interfaces and classes to implement the Observer pattern following these principles rather than using the JDK version.

 

Comparisons

Observer pattern is also called as Dependents pattern or Publish Subscribe pattern; however, few also say that they are not exactly the same.

I could find the below comparisons through a quick Google search:

Observer pattern vs. Mediator pattern

Observer pattern vs. Publish Subscribe

Observer pattern vs. Event Driven Approach

Observer pattern vs. Listeners

Observer pattern vs. Reactive programming

 

References

http://en.wikipedia.org/wiki/Observer_pattern

http://javajee.com/summary-of-important-design-principles

http://docs.oracle.com/javase/7/docs/api/java/util/Observable.html

http://docs.oracle.com/javase/7/docs/api/java/util/Observer.html

Head First Design Patterns By Eric Freeman, Elisabeth Freeman, Bert Bates, Kathy Sierra

Peeling Design Patterns Srinivasa Rao and Narasimha Karumanchi

Quick Notes Finder Tags

Activities (1) advanced java (1) agile (3) App Servers (6) archived notes (2) Arrays (1) Best Practices (12) Best Practices (Design) (3) Best Practices (Java) (7) Best Practices (Java EE) (1) BigData (3) Chars & Encodings (6) coding problems (2) Collections (15) contests (3) Core Java (All) (55) course plan (2) Database (12) Design patterns (8) dev tools (3) downloads (2) eclipse (9) Essentials (1) examples (14) Exception (1) Exceptions (4) Exercise (1) exercises (6) Getting Started (18) Groovy (2) hadoop (4) hibernate (77) hibernate interview questions (6) History (1) Hot book (5) http monitoring (2) Inheritance (4) intellij (1) java 8 notes (4) Java 9 (1) Java Concepts (7) Java Core (9) java ee exercises (1) java ee interview questions (2) Java Elements (16) Java Environment (1) Java Features (4) java interview points (4) java interview questions (4) javajee initiatives (1) javajee thoughts (3) Java Performance (6) Java Programmer 1 (11) Java Programmer 2 (7) Javascript Frameworks (1) Java SE Professional (1) JPA 1 - Module (6) JPA 1 - Modules (1) JSP (1) Legacy Java (1) linked list (3) maven (1) Multithreading (16) NFR (1) No SQL (1) Object Oriented (9) OCPJP (4) OCPWCD (1) OOAD (3) Operators (4) Overloading (2) Overriding (2) Overviews (1) policies (1) programming (1) Quartz Scheduler (1) Quizzes (17) RabbitMQ (1) references (2) restful web service (3) Searching (1) security (10) Servlets (8) Servlets and JSP (31) Site Usage Guidelines (1) Sorting (1) source code management (1) spring (4) spring boot (3) Spring Examples (1) Spring Features (1) spring jpa (1) Stack (1) Streams & IO (3) Strings (11) SW Developer Tools (2) testing (1) troubleshooting (1) user interface (1) vxml (8) web services (1) Web Technologies (1) Web Technology Books (1) youtube (1)