Architectural pattern: publisher-subscriber

Introduction

This pattern is also know as ’Observer’ (GoF). The mainly difference is that in architectural patterns there is a distinction for what is a components and what is a connectors. Here i want show just a basic working without this distinction. Besides i want show how implement it using the API of java, utility class that simplify the java implementation.

What is the problem

I have one or more objects (observer or listner or subscriber) that are interested to know when there are some events from another object (subject or publisher) and they want be informed when it happen. When that event happen the subscriber can perform their action that can be different from subscriber to subscriber.

How the publisher-subscriber work

The first thing to do for the subscribers (or observers) is registering to the publisher (or subject) so they can be notified when a event happen. To do that they just use attach() method of ConcreteSubject. When there is an event (that maybe also an internal change of state), in the ConcreteSubject, it notify all subscribers registered to it using notify() method. Internally this method action a call to all update() method of all subscrivers. Then, the update() methods perform their action (for example can call getState() method of their publisher, or doing any other action).

An example of implementation using java API

As i told, java has a utilty class that provide an API for the observer. The first is the interface java.util.Observable and the second is the class java.util.Observable. Now i want show an example using these.

In this example i want show that when a boiler get a temperature of 100 or 200 degree, it notify this to the two sensors. So the sensors get the temperature of boiler and perform their actions. To start we need to add the two subscriver to the bublisher using addObserver() method.

Boiler.java

package observer3;

import java.util.Observable;

public class Boiler extends Observable {

	private int state;

	public int getState() {
		return state;
	}

	public void setState(int state) {
		this.state = state;
		if (state==100){
			this.setChanged();
			this.notifyObservers();
		}
		if (state==200){
			this.setChanged();
			this.notifyObservers();
		}
		
	}
	
}
Sensor1.java

package observer3;

import java.util.Observable;
import java.util.Observer;

public class Sensor1 implements Observer {

	private Boiler boiler;
	
	@Override
	public void update(Observable arg0, Object arg1) {
		
		System.out.println("i am sensor1 and the temperature is "+boiler.getState()+" and i perform my action");

	}

	public Sensor1(Boiler boiler) {
		super();
		this.boiler = boiler;
	}

}
Sensor2.java

package observer3;

import java.util.Observable;
import java.util.Observer;

public class Sensor2 implements Observer {

	private Boiler boiler;
	
	@Override
	public void update(Observable o, Object arg) {

		System.out.println("i am sensor2 and the temperature is "+boiler.getState()+" and i perform my action");
		
	}

	public Sensor2(Boiler boiler) {
		super();
		this.boiler = boiler;
	}

}

It is to notice that when i set the state of boiler to 100, before calling the notifyObserver() method, i need to change the state of boiler using setChanged() method. If i don’t use setChanged() method the notifyObserver() doesn’t work. Basically that method mean that in boiler there was an event. so it’s ready to notify listeners. When notifyObserver() has finished, it internally call clearChanged() that mean the object is set as ’not changed’.

Test.java

package observer3;

public class Test {

	public static void main(String[] args) {
		
		Boiler b = new Boiler();
		Sensor1 s1 = new Sensor1(b);
		Sensor2 s2 = new Sensor2(b);
		
		b.addObserver(s1);
		b.addObserver(s2);
		
		b.setState(100);

	}

}
Output

i am sensor2 and the temperature is 100 and i perform my action
i am sensor1 and the temperature is 100 and i perform my action

Comments

Popular posts from this blog

Spring cloud config

Quick Sort algorithm with Java and R

SAX xml parser and Java