Chapter 15 - Design patterns for IO and storage

Designing for output

In the restaurant example, the UI needs to display the current state of the data. Polling is one expensive way of getting the current state. It would be better if the Application layer class informed the Presentation layer of any changes that happen, as they happen.

The responsibility for intiating UI updates is in the Application layout. The answer to this is to use the Observer Pattern. Used when a change to one object requires others to be changed and when one object needs to notify other objects of a change.

Observer pattern

Java.util provides an Observer interface and an Observable class. The class that is being observed extends Observable.

Observable object
import java.util.Observable;

public class BookingSystem extends Observable {
  public void someMethodChangingBookings() {
    // make changes
    notifyObservers("I've changed");
Observing object
public class StaffUI implements Observer {
  public void update(Observable obs, Object x) {
    Sysout.out.println(x + " says " + obs);

Something calls the relevant accessor method of a BookingSystem instance, bookingSystem. bookingSystem gets changed and it calls notifyObservers(). As a result, the update() method in each observer is called.

Achieving persistence : Serialisation

Serialisation provides a means of implementing persistence. The state of an object is saved to a file, and can be retrieved from a file. The attribute values in the object are 'frozen in time' with a save operation, and are retrieved with a get operation.

Serialisation proxy pattern

Rather than serialise an important object directly (which possibly will introduce bugs, and security problems), the object can serialise a "proxy" of itself.

  • The object itself is not serialised.
  • A "nested" class within the class of the object to be serialised.
  • The proxy has just those attributes that are eneded to preverse the state of the object.

The instance of the proxy class is serialised. The class itself implemented the writeReplace() method that is called during serialisation.

When de-serialising, use the serialised proxy and the attributes it contains, to recreate the object of interest. The proxy class has the readReceive() method needed to recreate the instance of the original class.