观察者模式,也叫发布订阅模式,定义对象之间的一种一对多的依赖关系,使得每当一个对象改变状态,则所有依赖于它的对象都会得到通知并被自动更新。
观察者模式的几个角色:
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);}@Overridepublic 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);}@Overridepublic String toString() {return getClass().getSimpleName();}}class ConcreteObserver1 implements Observer {@Overridepublic void update(Observable o, Object arg) {System.out.println("第一个 Observer!" + " 被观察者 : " + o + ", 观察的值为" + (arg instanceof Integer ? "整型" : "字符串") + ": " + arg);}}class ConcreteObserver2 implements Observer {@Overridepublic void update(Observable o, Object arg) {System.out.println("第二个 Observer!");}}}