Hello folks,

This post is all about to the Observer Design pattern.

There is common occurring problem where we need to define ” a one-to-many dependency between objects so that when one object changes state, all its dependents are notified and updated automatically “.

Everyday we subscribe the NewsLetter to get update emails. This is very much similar to as above said where NewsLetter status changes when new message added to NewsLetter, then all its subscribers should gets notified.

Observer Design pattern has 3 actors A Subject, an Observer and Observable objects.It is also called publisher-Subscriber Pattern.
887519-specialized-observer-pattern-class-diagram

Lets take this use case and try to implement Observer Design pattern..

Message object which is going to change an state of NewsLetter Object by simply adding to NewsLetter.

package com.message;

public class Message {
private String body;
     public Message(String body) {
        this.body = body;
    }

    public String getBody() {
        return body;
    }

    public void setBody(String body) {
        this.body = body;
    }
}

Message Type.

package com.message;

public class Email extends Message {

    private String from;
    private String subject;

    public Email(String from, String subject) {
        this.from = from;
        this.subject = subject;
    }

    public String getSubject() {
        return subject;
    }

    public void setSubject(String subject) {
        this.subject = subject;
    }

    public String getFrom() {
        return from;
    }

    public void setFrom(String from) {
        this.from = from;
    }
}

 NewsLetter as Subject class.

package com.subject;

import com.observer.Observer;

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

public class NewsLetter {
    private String  message;
    private List<Observer> observers;

    public NewsLetter() {
        message = new String();
        observers = new ArrayList<>();
    }

    public void addMessage(String message){
        this.message = message;
        notifyListeners(message);
    }

    public List<Observer> getObservers() {
        return observers;
    }

    public void removeListeners(Observer observer) {
        this.observers.remove(observer);
    }

    public void addListeners(Observer observer) {
        this.observers.add(observer);
    }

    public void notifyListeners(String message){
        // updating observers
        for(Observer observer : observers){
            observer.update(message);
        }
    }

}

We have List of Observers which are gets notified when NewsLetter object changes state (add an message to NewsLetter Object).Lets say we have only EmailObserver is Observer now added.

 Observer interface as Observer

package com.observer;

import com.message.Email;
import com.message.Message;

public interface Observer {
     void update(String message);
}

EmailObserver interface Implemention class

package com.observer;

import com.message.Email;
import com.message.Message;

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

public class EmailObserver implements Observer {
    private List<String> emails;
    private Email email;
    public EmailObserver() {
        emails = new ArrayList<String>();
    }

    @Override
    public void update(String message) {
        email = new Email("Admin@jellyfishTec.com","Hi this is subject");
        email.setBody(message);

        for(String emailAddress:emails) {
            System.out.println("To" + emailAddress);
            System.out.println("from....." + email.getFrom());
            System.out.println("Subject....." + email.getSubject());
            System.out.println("Body....." + email.getBody());
         }
        }
    public void subscribe(String email) {
        this.emails.add(email);
    }

    public void unsubscribe(String email) {
        this.emails.remove(email);
    }
}

In his class We have update method which will gets called when NewsLetter object changes state. I have added some println lines to display but these can be replaced with actual logic for sending an email.

This EmailObserver has also 2 methods for subscribing and unsubscribing an email from NewsLetter.These methods add or remove given email from subscription list.

Lets test it.

   package test;

import com.observer.EmailObserver;
import com.observer.SMSObserver;
import com.subject.NewsLetter;


public class test {
    public static void main(String[] args) {
        EmailObserver emailObserver = new EmailObserver();

                      emailObserver.subscribe("test1@user.com");
                      emailObserver.subscribe("test2@user.com");

        NewsLetter newsLetter = new NewsLetter();
        newsLetter.addListeners(emailObserver);
     
        newsLetter.addMessage("This is system generated text Message");
    }
}

At any time you can test this by adding or removing Observer from NewsLetter Observers list.
If you want to add new Observer,It is very simple.
Create new Observer.

package com.observer;

import com.message.Message;
import com.message.TextMessage;

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

public class SMSObserver implements Observer {
    private List<String> mobileNumbers;
    private TextMessage textMessage;

    public SMSObserver() {
        mobileNumbers= new ArrayList<>();
    }

    @Override
    public void update(String message) {
                 // creating text message
            textMessage =new TextMessage("Jellyfish Technologies");
            textMessage.setBody(message);
        // sending text message to subscribers.  
        for (String number : mobileNumbers) {
                System.out.println("To" + number);
                System.out.println("Text....." + textMessage.getBody());
            }
    }

    public void subscribe(String mobileNumber) {
        this.mobileNumbers.add(mobileNumber);
    }

    public void unsubscribe(String mobileNumber) {
        this.mobileNumbers.remove(mobileNumber);
    }
}

And Add this Observer to Subject Observers list nothing but add this Observer to NewsLetter observers list.

   // creating new Observer and its subscribers.
 SMSObserver smsObserver = new SMSObserver();
                    smsObserver.subscribe("123456");
                    smsObserver.subscribe("987654");
  
      // adding observer to Observers list
    newsLetter.addListeners(smsObserver)

Form now onwards both Observers will gets notified when State of NewsLetter has been changed.
At any time you can get rid off from notifcation by removing corresponding observer.

Hope This worked for you.