Java Tutorial/Design Pattern/Observable and Observer
Содержание
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);
}
}