Design Pattern Java Tutorial

import java.util.Observable;
import java.util.Observer;
class Library {
  private boolean isOpen;
  private OpenNotifier oNotify = new OpenNotifier();
  private CloseNotifier cNotify = new CloseNotifier();
  public Library() {
    isOpen = false;
  }
  public void open() { // Opens its petals
    isOpen = true;
    oNotify.notifyObservers();
    cNotify.open();
  }
  public void close() { // Closes its petals
    isOpen = false;
    cNotify.notifyObservers();
    oNotify.close();
  }
  public Observable opening() {
    return oNotify;
  }
  public Observable closing() {
    return cNotify;
  }
  private class OpenNotifier extends Observable {
    private boolean alreadyOpen = false;
    public void notifyObservers() {
      if (isOpen && !alreadyOpen) {
        setChanged();
        super.notifyObservers();
        alreadyOpen = true;
      }
    }
    public void close() {
      alreadyOpen = false;
    }
  }
  private class CloseNotifier extends Observable {
    private boolean alreadyClosed = false;
    public void notifyObservers() {
      if (!isOpen && !alreadyClosed) {
        setChanged();
        super.notifyObservers();
        alreadyClosed = true;
      }
    }
    public void open() {
      alreadyClosed = false;
    }
  }
}
class Student {
  private String name;
  private OpenObserver openObsrv = new OpenObserver();
  private CloseObserver closeObsrv = new CloseObserver();
  public Student(String nm) {
    name = nm;
  }
  private class OpenObserver implements Observer {
    public void update(Observable ob, Object a) {
      System.out.println("Student " + name + "'s study time!");
    }
  }
  private class CloseObserver implements Observer {
    public void update(Observable ob, Object a) {
      System.out.println("Student " + name + "'s bed time!");
    }
  }
  public Observer openObserver() {
    return openObsrv;
  }
  public Observer closeObserver() {
    return closeObsrv;
  }
}
class Professor {
  private String name;
  private OpenObserver openObsrv = new OpenObserver();
  private CloseObserver closeObsrv = new CloseObserver();
  public Professor(String nm) {
    name = nm;
  }
  private class OpenObserver implements Observer {
    public void update(Observable ob, Object a) {
      System.out.println("Professor " + name + "'s research time!");
    }
  }
  private class CloseObserver implements Observer {
    public void update(Observable ob, Object a) {
      System.out.println("Professor " + name + "'s bed time!");
    }
  }
  public Observer openObserver() {
    return openObsrv;
  }
  public Observer closeObserver() {
    return closeObsrv;
  }
}
public class ObservedFlower {
  public static void main(String args[]) {
    Library f = new Library();
    Student ba = new Student("A"), bb = new Student("B");
    Professor ha = new Professor("A"), hb = new Professor("B");
    f.opening().addObserver(ha.openObserver());
    f.opening().addObserver(hb.openObserver());
    f.opening().addObserver(ba.openObserver());
    f.opening().addObserver(bb.openObserver());
    f.closing().addObserver(ha.closeObserver());
    f.closing().addObserver(hb.closeObserver());
    f.closing().addObserver(ba.closeObserver());
    f.closing().addObserver(bb.closeObserver());
    f.opening().deleteObserver(hb.openObserver());
    f.open();
    f.closing().deleteObserver(ba.closeObserver());
    f.close();
    f.opening().deleteObservers();
    f.open();
    f.close();
  }
}