观察者模式,也叫发布订阅模式,定义对象之间的一种一对多的依赖关系,使得每当一个对象改变状态,则所有依赖于它的对象都会得到通知并被自动更新。
观察者模式的几个角色:
Subject被观察者:定义被观察者必须实现的职责,它必须能够动态地增加、取消观察者。它一般是抽象类或者是实现类,仅仅是完成作为被观察者必须实现的职责。
Observer观察者:观察者收到消息后,即进行update(更新方法)操作,对接收到的信息进行处理。
ConcreteSubject具体的被观察者:定义被观察者自己的业务逻辑,同时定义哪些事件进行通知。
ConcreteObserver具体的观察者:每个观察者在接受到消息后的处理反应是不同,各个观察者有自己的处理逻辑。
1. 代码
// 被观察者
public abstract class Subject {
// 定一个一个观察者数组 ArrayList是线程异步,不安全,Vector是线程同步,安全
private Vector<Observer> obsVector = new Vector<Observer>();
// 增加一个观察者
public void addObserver(Observer o) {
this.obsVector.add(o);
}
// 删除一个观察者
public void delObserver(Observer o) {
this.obsVector.remove(o);
}
// 通知所有观察者
public void notifyObserver() {
for (Observer o : this.obsVector) {
o.update();
}
}
}
// 具体的被观察者
public class ConcreteSubject extends Subject {
// 具体的业务
public void doSomething() {
/*
* do something
*/
super.notifyObserver();
}
}
// 观察者
public interface Observer {
// 更新方法
public void update();
}
// 具体观察者
public class ConcreteObserver implements Observer {
// 实现更新方法
public void update() {
System.out.println("接收到信息,并进行处理!");
}
}
// 场景类
public class Client {
public static void main(String[] args) {
// 创建一个被观察者
ConcreteSubject subject = new ConcreteSubject();
// 定义一个观察则
Observer obs = new ConcreteObserver();
// 观察者观察被被观察则
subject.addObserver(obs);
// 观察者开始活动了
subject.doSomething();
}
}
2. 使用java.util包中的标准类实现观察者模式
JDK提供了对观察者模式的支持接口和实现类。
其中接口 java.util.Observer 用来指定观察者,观察者必须实现 void update(Observable o, Object arg) 方法,参数 Observable o 用于指定触发 update 方法的对象, Object arg 用于指定触发 update 方法时候的附加参数。而 java.util.Observable 用来指定观察物(被观察者、可被观察的),并且提供了一系列的方法。
import java.util.Observable;
import java.util.Observer;
/**
* 使用java.util包中的标准类实现观察者模式
*/
public class ObserverClient {
public static void main(String[] args) {
ObserverClient client = new ObserverClient();
// 被观察者
ConcreteSubject1 subject1 = client.new ConcreteSubject1(1);
ConcreteSubject2 subject2 = client.new ConcreteSubject2("userek");
// 观察者
Observer observer1 = client.new ConcreteObserver1();
Observer observer2 = client.new ConcreteObserver2();
// 注册
subject1.addObserver(observer1);
subject1.addObserver(observer2);
subject2.addObserver(observer1);
// 改变被观察者状态,触发观察者回调函数
subject1.doSomething();
subject2.doSomething();
}
class ConcreteSubject1 extends Observable {
private int mSubjectValue;
private ConcreteSubject1(int mSubjectValue) {
super();
this.mSubjectValue = mSubjectValue;
}
public void doSomething() {
setChanged();
notifyObservers(mSubjectValue);
}
@Override
public String toString() {
return getClass().getSimpleName();
}
}
class ConcreteSubject2 extends Observable {
private String mSubjectName;
private ConcreteSubject2(String mSubjectName) {
super();
this.mSubjectName = mSubjectName;
}
public void doSomething() {
setChanged();
notifyObservers(mSubjectName);
}
@Override
public String toString() {
return getClass().getSimpleName();
}
}
class ConcreteObserver1 implements Observer {
@Override
public void update(Observable o, Object arg) {
System.out.println("第一个 Observer!" + " 被观察者 : " + o + ", 观察的值为"
+ (arg instanceof Integer ? "整型" : "字符串") + ": " + arg);
}
}
class ConcreteObserver2 implements Observer {
@Override
public void update(Observable o, Object arg) {
System.out.println("第二个 Observer!");
}
}
}