Monday, June 20, 2022

Design Pattern: Observer Pattern

Chapters

Observer Pattern

Observer pattern is a design pattern that consists of observers and a subject. Subject is an entity that is being observed by observers. Observer is an entity that observes the Subject. Most event handling systems implement observer pattern.

This example demonstrates observer pattern.
import java.util.ArrayList;

public class ClientCode{

  public static void main(String[] args){
    Subject playerOne = new Controller("Player One");
    Subject playerTwo = new Controller("Player Two");
    Subject.Observer input = new InputManager();
    
    playerOne.addObserver(input);
    playerTwo.addObserver(input);
    
    playerOne.moveUp();
    playerTwo.moveDown();
  }
}

abstract class Subject{
  private String name;
  private ArrayList<Observer> obsList = 
  new ArrayList<>();
  
  Subject(String name){
    this.name = name;
  }
  
  public void addObserver(Observer obs){
    obsList.add(obs);
  }
  
  public void removeObserver(Observer obs){
    obsList.remove(obs);
  }
  
  private void notifyObservers(String name, String event){
    obsList.
    stream().
    forEach(obs -> obs.update(name, event));
  }
  
  public static abstract class Observer{

    protected abstract void update(String name, String event);
  }
  
  public void moveUp(){
    notifyObservers(name, "up");
  }
  
  public void moveDown(){
    notifyObservers(name, "down");
  }
  
}

class Controller extends Subject{
  
  Controller(String name){
    super(name);
  }
}

class InputManager extends Subject.Observer{
  
  @Override
  protected void update(String name, String event){
    System.out.println
    (name + " pressed " + event + " button.");
    System.out.println
    ("InputManager updates the monitor screen and"+ 
    " moves its character " + event + ".");
  }
}

Result
Player One pressed up button.
InputManager updates the monitor screen and moves its character up.
Player Two pressed down button.
InputManager updates the monitor screen and moves its character down.
In the example above, observer and subject are still tightly coupled. The observer design above is alright but if you want to decouple the two further, you may wanna use publish-subscribe pattern where publishers are subjects and subscribers are observers.

Unlike in the example above, publish-subscribe pattern doesn't send a message directly to observers. It instead sends the message to an entity and that entity sends the message to observers. In java, Flow API implements publish-subscribe pattern. I discussed the API in this article.

If your observers are being notified in quick succession, you may want to implement a timer in order to improve the performance of your application. One example that this scenario may happen is redrawing a GUI window. Everytime we redraw the window on our screen, observers that observe the redrawing process will be notified.

No comments:

Post a Comment