Saturday, September 28, 2019

Observer Design Pattern In Java

Greetings!

Greetings!

Observer design pattern falls into behavioral category.

Observer design pattern is useful when we have multiple objects doing things according to another objects changes.
This main object is callsed Subject and depending objects are called Observers.

  • Subject and observers are loosely coupled and have no knowledge of each other.
Subject(one) ----> Observer(many)

Swing event listner, Spring listner are some examples for Observer desgin pattern.

Observer design pattern according to GoF,
"Define a one-to-many dependency between objects so that when one object changes state, all its dependencies are notified and updated automatically."



Subject

Maintain a list of observers who are interested in getting notified when something useful is happend.
This provides methods to register the Observer, unregister the Observer and a method to notify all Observers at once.

Observer

Object which is interested in Subject's changes. Has a method to get updates from the Subject.

Why not use built in Observer?

Java util library provides a built in Observer pattern which we can use. Unfortunately it has few drawbacks hence not widely used.
Observable is class which we have to extend limiting us extending another class.
Use a Vector to maintain Observers which is synchronized and outdated.
Methods are synchronized.

This is very easy pattern to implement. So we should not depend on the in-built pattern.

Working Example

For our example i'm going to use an ordering system which user place an order. After completing the order user may get an email also the print out of the order.
Here, order is the Subject, email and print are Observering the order.

Let's start defining our Observable interface.

package com.slmanju.patterns;

public interface Observable {

    void attachObserver(Observer observer);

    void removeObserver(Observer observer);

    void sendNotification();

}


Now we need Observer interface.

package com.slmanju.patterns;

public interface Observer {

    void update(Order order);

}


Then we need a concrete Subject which is our Order class.

package com.slmanju.patterns;

import java.util.ArrayList;
import java.util.List;

public class Order implements Observable {

    private List observers;

    public Order() {
        this.observers = new ArrayList<>();
    }

    public void complete() {
        System.out.println("Completing the order");
        sendNotification();
    }

    @Override
    public void attachObserver(Observer observer) {
        observers.add(observer);
    }

    @Override
    public void removeObserver(Observer observer) {
        observers.remove(observer);
    }

    @Override
    public void sendNotification() {
        observers.forEach(observer -> observer.update(this));
    }

}


Now we can implement our Observers.

package com.slmanju.patterns;

public class OrderEmail implements Observer {

    @Override
    public void update(Order order) {
        System.out.println("Sending order email");
    }

}

package com.slmanju.patterns;

public class OrderPrinter implements Observer {

    @Override
    public void update(Order order) {
        System.out.println("Printing order");
    }

}


All set. Let's try our application by creating an order.

package com.slmanju.patterns;

public class App {

    public static void main(String[] args) {
        Order order = new Order();
        order.attachObserver(new OrderPrinter());
        order.attachObserver(new OrderEmail());

        order.complete();
    }

}


That is all for Observer design pattern. Remember to;
  • Strive for loosely coupled designs between objects that interact.

No comments:

Post a Comment