23 Classical Design Patterns - 34 - Extension of Observer Patterns

Posted by Arbitus on Tue, 01 Oct 2019 19:19:09 +0200

1. Expansion of the Observer Model

As I mentioned in my last blog, there are two problems with the standard observer model defined by the Gang of Four:

  • Observers need to hold references from specific observers, which leads to strong coupling between the observer and the observee.
  • The observer update method needs to call the observee's method to get real-time status. Although this is designed to minimize the quantification of messages at message notification, in multithreading, we may not be in the state at which the changes are actually triggered. Therefore, we can make improvements in this way. The updating method of the observer receives a parameter and receives the changed content.

1.1 Extended Schema-Class Diagram

According to the above questions, the author changes the standard observer model as follows:

  • The Abstract observer pattern is upgraded to an interface to ensure more versatility and flexibility
  • Specific observer pattern needs to realize the logic of observer management and notification, and can also add a layer of abstraction between them.
  • A new parameter is added to the updating method of the observer's role, which is used to pass in the factors that trigger the notification method.
  • The specific observer is no longer coupled with the observer, no longer holds the reference to the observer, and the update method does not need to query the status.

1.2 Observed pattern-abstract interface

The observer pattern is abstracted as an interface, and the management of the observer is subsided to a specific subclass.

public interface ISubject {

    public void attach(Observer observer);

    public void detach(Observer observer);

    public void notifyObservers(Object object);
}

1.3 Specific Observed - Temperature Subject

It is necessary to implement the method of observer management and notification.

public class TemperatureSubject implements ISubject {

    // Store a list of observers
    private LinkedList<Observer> observers = new LinkedList<>();

    // Save the current temperature
    private String temperature;

    public void setTemperature(String temperature) {
        this.temperature = temperature;

        System.out.println("Update the current temperature to:" + temperature + " degree");

        // Notify the observer
        this.notifyObservers(temperature);
    }

    public String getTemperature() {
        return this.temperature;
    }

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

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

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

1.4 Observer

public interface Observer {

    // Update method: Update operation after receiving notification
    public void update(Object object);
}

1.5 web Observer

The update method receives the change message directly without re-querying.

public class WebObserver implements Observer {

    @Override
    public void update(Object temperature) {
        System.out.println("Web-Receive a message, The current temperature is:" + temperature + " degree");
    }
}

1.6 app Observer

The update method receives the change message directly without re-querying.

public class AppObserver implements Observer {

    @Override
    public void update(Object temperature) {
        System.out.println("App-Receive a message, The current temperature is:" + temperature + " degree");
    }
}