Observer design pattern

M.Khalil ANEBDOUR
5 min readSep 3, 2020
https://www.pexels.com/fr-fr/photo/personne-gens-femme-retro-3769697/

INTRODUCTION

In the previous post we talked about the singleton design pattern, but generic, now let’s take a look at one of the most important behavioral designs out there, which is Observer design pattern, used in event handling for example.

What is Observer design pattern?

https://www.pexels.com/fr-fr/photo/adulte-beaux-yeux-bouche-cil-1715091/

Briefly Imagine we have two entities one of them -named observer- needs to know if the data in the other entity -named observable- changed so that it can do some logic (maybe use this data).
Let’s look at this example: Medium article container and Medium subscribers, in this case the article container is our Observable and the subscribers are the Observers, they need to know if a new article is out there so that they can go and check it out, so this is the major idea behind this pattern, and we call it One to many structure, because we can have many observers observe one observable.

One To many

Problematic:

To do this we can think of making calls from each observer to the observable and check if the data has changed or not, every second for example, and we keep doing this, which’s bad, because we are asking for data before knowing if it exists, the logic will be executed many times, and maybe the observable data will change in half second, so that we will not get any result (╬ಠ益ಠ) .It’s called Poll networking architecture.

Solution:

To solve this problem we will use the Observer pattern, in stand of each observer check if the data has changed, the observable Broadcasts to the observers once any change has been detected: “Hi, data are changed, do what you get to do”, and before that the observers need to register to this observable

(Registration == to create the connection,

Observer: What am i going to observe?

Observable: who should I notify?)

to make sure that all registered observers will be notified if the data has changed, (It’s like Youtube bells to get notified every time a new video is out ¯\_༼ ಥ ‿ ಥ ༽_/¯ ).

UML diagram:

Observable pattern (There is many presentation)

Design patterns is about abstraction, this’s why we use interfaces.

IObservable it’s a contract, interface with 3 signatures:

Register(IObserver): Observer subscribes or registers to an observable to get notified if it changed;

Unregister(IObserver): Opposite of Register, (the use of this one depends on your situation);

Notify(): Observable will notify all his observers.

And IObserver contract with one signature Update ();

the Observer, after getting the observable event, it will call this method to do the logic, (getting data from Observable for example);

And finally, Concret_observble implements IObservable and Concret_observer implements IObserver.

Question ??

What about the composition between Concret_observbale and Concret_observer?

Concret_observer has a Concret_observble so that when the observer calls update method he knows where he can find data for example, it’s just about getting access to data source, imagine if we didn’t make this composition, when the observer calls Update(), it needs to know where the data is to process :

observerInstance.update(); ??

// update what ?, and where can i the resource !? !(•̀ᴗ•́)و ̑̑

to resolve this we have 2 solutions :

1• Adding Observable in the update parameter in IObserver interface

2• Doing this composition.(We will see it in the code)

both are coupling which’s bad BUT the second one is better

Did we break the single responsibility principle in the Concret_observble class?

YES, we did, because this class content other method to process data, and Register, Notify & Unregister methods which has many reasons to change! but we can let it go or instead of having IObservable as an interface we can change it to abstract class, and Concret_observbale will extend it, and now SRP is valid.

Now Let’s look at some code

Let’s take an example, imagine a milk factory contains, delivery service and budget service, and when factory production achieves for example 50L of milk, then delivery service will start delivering milk and budget service will start paying employees.

public interface IObservable {
void Register(IObserver observer);
void Unregister(IObserver observer);
void Notify();
}
public interface IObserver {
void update();
}
// When the observable when to inform observers, that data has
// changed he will execute the notify method but inside, each //observer in registration list will run this update method to do //the logic
public class Delivery_service implements IObserver{

private Milk_factory data;

public Delivery_service(Milk_factory data) {
this.data = data;
}

@Override
public void update() {
System.out.println("delivery: " + data.getProductionNb());
}
}
public class Budget_service implements IObserver{

private Milk_factory data;

public Budget_service(Milk_factory data) {
this.data = data;
}
@Override
public void update() {
System.out.println("budge: " + data.getProductionNb());
}
}
public class Milk_factory implements IObservable{

private int productionNb;
private List<IObserver> registrations = new ArrayList<IObserver>();

public Milk_factory(int productionNb) {
this.productionNb = productionNb;
}

@Override
public void Register(IObserver observer) {
this.registrations.add(observer);
}
@Override
public void Unregister(IObserver observer) {
this.registrations.remove(observer);
}
@Override
public void Notify() {
if(this.productionNb >= 50){
this.registrations.stream()
.forEach(observer -> observer.update());
}
}

public int getProductionNb() {
return productionNb;
}
public void setProductionNb(int productionNb) {
this.productionNb = productionNb;
}
}
public class App {public static void main(String[] args) {
Milk_factory milker = new Milk_factory(5);

Budget_service budget = new Budget_service(milker);
Delivery_service delivery = new Delivery_service(milker);

// budget and delivery need to register to milker
milker.Register(budget);
milker.Register(delivery);

milker.Notify(); // nothing happened productionNb is 5 L

milker.setProductionNb(51);
// now milker will go and notify every observer in
// his registrations list by calling update
milker.Notify();
}
}

Budget_service and Delivery_service are observers and Milk_factory observable.

Find me on Github

So What do you think?

And feel free to leave your feedback for me.

Facebook, Instagram, Twitter

Thanks so much ᕕ( ᐛ )ᕗ

--

--

M.Khalil ANEBDOUR

Financial market R&D engineer, Eager to learn new things. ✌🏼