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"); } }