引用百度百科,观察者模式概念:观察者模式(Observer)是软件设计模式的一种,在此模式中,一个目标物件管理所有依附于它的所有观察者物件,并且在它本身的状态发生改变时主动发出通知。这通常通过呼叫观察者实现的方法来实现,此种常被用来实现事件处理系统,例如事件驱动模型
1.JDK中的观察者模式设计
用一个UML图看下JDK提供了我们哪些接口和类:
Observer:观察者。
Observerable:可观察的,相当于Subject,被观察者。
Observerable中使用布尔类型值changed标识被观察者状态是否改变,Vector作为Observer观察者容器,存放所有的观察者对象;提供了一系列对观察者对象的方法,添加、删除、通知观察者、观察者对象计数。想要查看源码的可以去JDK>rt.jar>java>util包下查看
案例
观察者MyObserverA:
import java.util.Observable;
import java.util.Observer;
/**
* 观察者A
* @author zisong yue
* @date 2018-12-03
*/
public class MyObserverA implements Observer {
@Override
public void update(Observable o, Object arg) {
System.out.println("MyObserverA update status");
}
}
观察者MyObserverB
import java.util.Observable;
import java.util.Observer;
/**
* 观察者B
* @author zisong yue
* @date 2018-12-03
*/
public class MyObserverB implements Observer {
@Override
public void update(Observable o, Object arg) {
System.out.println("MyObserverB update state");
}
}
被观察者MyObserverable
import java.util.Observable;
import java.util.Observer;
/**
* 被观察者
* @author zisong yue
* @date 2018-12-03
*/
public class MyObserverable extends Observable {
@Override
public synchronized void addObserver(Observer o) {
super.addObserver(o);
}
@Override
public void notifyObservers() {
super.notifyObservers();
}
@Override
protected synchronized void setChanged() {
super.setChanged();
}
}
测试类ObserverTest
/**
* 测试类
* @author zisong yue
* @date 2018-12-03
*/
public class ObserverTest {
public static void main(String[] args) {
MyObserverable observerable = new MyObserverable();
MyObserverA observerA = new MyObserverA();
MyObserverB observerB = new MyObserverB();
observerable.addObserver(observerA);
observerable.addObserver(observerB);
observerable.setChanged();
observerable.notifyObservers();
}
}
测试结果:
测试结果说明,当被观察者对象MyObserverable状态改变时,通知了所有已注册的观察者对象。
2.JDK中事件驱动模型设计
事件驱动模型一般包含以下几个内容:
事件源:顾名思义,就是产生事件的地方
事件:具体的行为
事件监听器:针对事件做出相应的动作,可以在监听器中处理一些业务逻辑
JDK中有个针对javaBean属性的事件驱动,我们先看下怎么用的,然后一起看下源码怎么实现的
Person类:
我们先看一个例子,然后再看下
import java.beans.PropertyChangeListener;
import java.beans.PropertyChangeSupport;
/**
* Person类是事件源
* @author zisong yue
* @date 2018-12-04
*/
public class Person{
private PropertyChangeSupport changeSupport;
private String name;
private String sex;
private int age;
Person(){
changeSupport = new PropertyChangeSupport(this);
this.name = "张三";
this.age = 13;
this.sex = "男";
}
/**
* 给所有属性添加监听器
*/
public void addCommonListen(PropertyChangeListener changeListener){
changeSupport.addPropertyChangeListener(changeListener);
}
/**
* 给指定属性添加监听器
*/
public void addNamedListen(String propertyName, PropertyChangeListener changeListener){
changeSupport.addPropertyChangeListener(propertyName, changeListener);
}
public void setName(String name) {
fireChange("name", this.name, name);
this.name = name;
}
public void setSex(String sex) {
fireChange("sex", this.sex, sex);
this.sex = sex;
}
public void setAge(int age) {
fireChange("age", this.age, age);
this.age = age;
}
/**
* 属性值改变通知公共监听器和指定属性的监听器
*/
public void fireChange(String propertyName, Object oldValue, Object newValue){
changeSupport.firePropertyChange(propertyName, oldValue, newValue);
}
public static void main(String[] args) {
Person person = new Person();
person.addCommonListen(new ListenerPropertyCommon());
person.addNamedListen("name",new ListenerPropertyName());
person.addNamedListen("age", new ListenerPropertyAge());
person.addNamedListen("sex", new ListenerPropertySex());
person.setName("张三2");
person.setAge(14);
person.setSex("女");
}
}
各个属性的监听类和公共监听类
所有属性的监听器(即可以监听所有属性的变化):
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
/**
* 监听所有属性
* @author zisong yue
* @date 2018-12-05
*/
public class ListenerPropertyCommon implements PropertyChangeListener {
@Override
public void propertyChange(PropertyChangeEvent evt) {
System.out.println("ListenerPropertyCommon receive message, The PropertyName:" + evt.getPropertyName() + " is changed, oldValue:" + evt.getOldValue() +
" newValue:" + evt.getNewValue());
}
}
name属性监听器:
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
/**
* name属性监听器
* @author zisong yue
* @date 2018-12-05
*/
public class ListenerPropertyName implements PropertyChangeListener{
@Override
public void propertyChange(PropertyChangeEvent evt) {
System.out.println("ListenerPropertyName receive message, The PropertyName:" + evt.getPropertyName() + " is changed, oldValue:" + evt.getOldValue() +
" newValue:" + evt.getNewValue());
}
}
age属性监听器:
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
/**
* age属性监听器
* @author zisong yue
* @date 2018-12-05
*/
public class ListenerPropertyAge implements PropertyChangeListener{
@Override
public void propertyChange(PropertyChangeEvent evt) {
System.out.println("ListenerPropertyAge receive message, The PropertyName:" + evt.getPropertyName() + " is changed, oldValue:" + evt.getOldValue() +
" newValue:" + evt.getNewValue());
}
}
sex属性监听器:
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
/**
* sex属性监听器
* @author zisong yue
* @date 2018-12-05
*/
public class ListenerPropertySex implements PropertyChangeListener{
@Override
public void propertyChange(PropertyChangeEvent evt) {
System.out.println("ListenerPropertySex receive message, The PropertyName:" + evt.getPropertyName() + " is changed, oldValue:" + evt.getOldValue() +
" newValue:" + evt.getNewValue());
}
}
执行Person中main方法,测试结果:
可以看到,Common监听器对所有属性的值的变化做出了相应,其他各自属性的监听器也做出了对应的相应
源码分析:
PropertyChangeSupport:相当于事件源,里面维护了一个PropertyChangeListenerMap(监听器添加到这里)
源码挺简单,就不再详细的解释了,有兴趣的可去JDK的rt.jar java>beans包下去看,都写了JAVADOC,很详细