Java Tutorial/Design Pattern/Observable and Observer

Материал из Java эксперт
Перейти к: навигация, поиск

An object may be observed by two or more observers.

   <source lang="java">

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

}</source>





Demonstrate the Observable class and the Observer interface.

   <source lang="java">

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

}</source>





Demonstration of "observer" pattern.

   <source lang="java">

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

}</source>





Observable and Observer Objects

   <source lang="java">

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

}</source>



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

   <source lang="java">

/*

* 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 ExecuteWatchdog
* 
* @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);

}</source>





Watch What is Going On with the Observer Patterns

   <source lang="java">

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

}</source>