Java Tutorial/Design Pattern/Observable and Observer

Материал из Java эксперт
Версия от 17:44, 31 мая 2010; (обсуждение)
(разн.) ← Предыдущая | Текущая версия (разн.) | Следующая → (разн.)
Перейти к: навигация, поиск

An object may be observed by two or more observers.

import java.util.Observable;
import java.util.Observer;
class Watcher1 implements Observer {
  public void update(Observable obj, Object arg) {
    System.out.println("update() called, count is " + ((Integer) arg).intValue());
  }
}
class Watcher2 implements Observer {
  public void update(Observable obj, Object arg) {
    if (((Integer) arg).intValue() == 0)
      System.out.println("Done");
  }
}
class BeingWatched extends Observable {
  void counter(int period) {
    for (; period >= 0; period--) {
      setChanged();
      notifyObservers(new Integer(period));
      try {
        Thread.sleep(100);
      } catch (InterruptedException e) {
        System.out.println("Sleep interrupted");
      }
    }
  }
}
class MainClass {
  public static void main(String args[]) {
    BeingWatched observed = new BeingWatched();
    Watcher1 observing1 = new Watcher1();
    Watcher2 observing2 = new Watcher2();
    observed.addObserver(observing1);
    observed.addObserver(observing2);
    observed.counter(10);
  }
}





Demonstrate the Observable class and the Observer interface.

import java.util.Observable;
import java.util.Observer;
class Watcher implements Observer {
  public void update(Observable obj, Object arg) {
    System.out.println("update() called, count is " + ((Integer) arg).intValue());
  }
}
class BeingWatched extends Observable {
  void counter(int period) {
    for (; period >= 0; period--) {
      setChanged();
      notifyObservers(new Integer(period));
      try {
        Thread.sleep(100);
      } catch (InterruptedException e) {
        System.out.println("Sleep interrupted");
      }
    }
  }
}
class ObserverDemo {
  public static void main(String args[]) {
    BeingWatched observed = new BeingWatched();
    Watcher observing = new Watcher();
    observed.addObserver(observing);
    observed.counter(10);
  }
}





Demonstration of "observer" pattern.

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.open();
    f.closing().deleteObserver(ba.closeObserver());
    f.close();
    f.close();
    f.opening().deleteObservers();
    f.open();
    f.close();
  }
}





Observable and Observer Objects

import java.util.Observable;
import java.util.Observer;
class MyObservable extends Observable {
  public void drinkPotion() {
    name = "jexp ";
    setChanged();
    notifyObservers();
  }
  public String getName() {
    return name;
  }
  private String name = "jexp";
}
class Person implements Observer {
  public Person(String name, String says) {
    this.name = name;
    this.says = says;
  }
  public void update(Observable thing, Object o) {
    System.out.println("It"s " + ((MyObservable) thing).getName() + "\n" + name + ": " + says);
  }
  private String name;
  private String says;
}
public class MainClass {
  public static void main(String[] args) {
    MyObservable man = new MyObservable();
    Observer[] crowd = { 
        new Person("A", "a"),
        new Person("B", "b"),
        new Person("C", "c"),
        new Person("D", "d"),
        new Person("E", "e") };
    for (Observer observer : crowd) {
      man.addObserver(observer);
    }
    man.drinkPotion();
  }
}



It"s jexp 
E: e
It"s jexp 
D: d
It"s jexp 
C: c
It"s jexp 
B: b
It"s jexp 
A: a">


Timeout Observer

/* 
 * Licensed to the Apache Software Foundation (ASF) under one or more
 *  contributor license agreements.  See the NOTICE file distributed with
 *  this work for additional information regarding copyright ownership.
 *  The ASF licenses this file to You under the Apache License, Version 2.0
 *  (the "License"); you may not use this file except in compliance with
 *  the License.  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 *
 */
import java.util.Enumeration;
import java.util.Vector;
/**
 * Generalization of <code>ExecuteWatchdog</code>
 * 
 * @see org.apache.rumons.exec.ExecuteWatchdog
 */
public class Watchdog implements Runnable {
  private Vector observers = new Vector(1);
  private final long timeout;
  private boolean stopped = false;
  public Watchdog(final long timeout) {
    if (timeout < 1) {
      throw new IllegalArgumentException("timeout must not be less than 1.");
    }
    this.timeout = timeout;
  }
  public void addTimeoutObserver(final TimeoutObserver to) {
    observers.addElement(to);
  }
  public void removeTimeoutObserver(final TimeoutObserver to) {
    observers.removeElement(to);
  }
  protected final void fireTimeoutOccured() {
    Enumeration e = observers.elements();
    while (e.hasMoreElements()) {
      ((TimeoutObserver) e.nextElement()).timeoutOccured(this);
    }
  }
  public synchronized void start() {
    stopped = false;
    Thread t = new Thread(this, "WATCHDOG");
    t.setDaemon(true);
    t.start();
  }
  public synchronized void stop() {
    stopped = true;
    notifyAll();
  }
  public synchronized void run() {
    final long until = System.currentTimeMillis() + timeout;
    long now;
    while (!stopped && until > (now = System.currentTimeMillis())) {
      try {
        wait(until - now);
      } catch (InterruptedException e) {
      }
    }
    if (!stopped) {
      fireTimeoutOccured();
    }
  }
}
/**
 * Interface for classes that want to be notified by Watchdog.
 * 
 * @see org.apache.rumons.exec.Watchdog
 */
interface TimeoutObserver {
  /**
   * Called when the watchdow times out.
   * 
   * @param w
   *          the watchdog that timed out.
   */
  void timeoutOccured(Watchdog w);
}





Watch What is Going On with the Observer Patterns

import java.util.Vector;
public class TestObserver {
  public static void main(String args[]) {
    Database database = new Database();
    Archiver archiver = new Archiver();
    Client client = new Client();
    Boss boss = new Boss();
    database.registerObserver(archiver);
    database.registerObserver(client);
    database.registerObserver(boss);
    database.editRecord("delete", "record 1");
  }
}
interface Observer {
  public void update(String operation, String record);
}
interface Subject {
  public void registerObserver(Observer o);
  public void removeObserver(Observer o);
  public void notifyObservers();
}
class Database implements Subject {
  private Vector<Observer> observers;
  private String operation;
  private String record;
  public Database() {
    observers = new Vector<Observer>();
  }
  public void registerObserver(Observer o) {
    observers.add(o);
  }
  public void removeObserver(Observer o) {
    observers.remove(o);
  }
  public void notifyObservers() {
    for (int loopIndex = 0; loopIndex < observers.size(); loopIndex++) {
      Observer observer = (Observer) observers.get(loopIndex);
      observer.update(operation, record);
    }
  }
  public void editRecord(String operation, String record) {
    this.operation = operation;
    this.record = record;
    notifyObservers();
  }
}
class Client implements Observer {
  public Client() {
  }
  public void update(String operation, String record) {
    System.out.println("The client says a " + operation + " operation was performed on " + record);
  }
}
class Boss implements Observer {
  public Boss() {
  }
  public void update(String operation, String record) {
    System.out.println("The boss says a " + operation + " operation was performed on " + record);
  }
}
class Archiver implements Observer {
  public Archiver() {
  }
  public void update(String operation, String record) {
    System.out
        .println("The archiver says a " + operation + " operation was performed on " + record);
  }
}