观察者模式(observer pattern)
一、定义
所谓观察者模式,就是在一个subject对象中封装一个或者多个observer对象。如果subject对象的状态发送改变,同时通知observer对象做出相应的动作
二、理论举例
只是一个个人根据定义实现的例子
1)subject
public class Subject {
protected List<Observer> observers=new ArrayList<>();
private int state;
//从来关联观察者的方法
public void attach(Observer observer){
observers.add(observer);
}
//解除关联
public void detach(Observer observer){
observers.remove(observer);
}
//通知所有观察者 subject的状态发生了改变
public void notifyAllObserver(){
for(Observer observer:observers){
observer.update(this);
}
}
public int getState() {
return state;
}
public void setState(int state) {
this.state = state;
this.notifyAllObserver();
}
}
2)observer
抽象接口
public abstract class Observer {
//状态改变时,观察者做出的操作
public abstract void update(Subject subject);
}
具体实现
Observer01
public class Observer01 extends Observer{
private int observerState;
@Override
public void update(Subject subject) {
System.out.println(Observer01.class.getName()+" state:"+observerState+">>"+subject.getState());
this.observerState=subject.getState();
}
}
Observer02
public class Observer02 extends Observer{
private int observerState;
@Override
public void update(Subject subject) {
System.out.println(Observer02.class.getName()+" state:"+observerState+">>"+subject.getState());
this.observerState=subject.getState();
}
}
3)测试
测试的类
public class ObserverPatternMain {
public static void main(String[] args) {
Subject subject=new Subject();
Observer01 observer01=new Observer01();
Observer02 observer02=new Observer02();
subject.attach(observer01);
subject.attach(observer02);
subject.setState(2);
}
}
测试结果
cn.faceless.ObserverPattern.theory.Observer01 state:0>>2
cn.faceless.ObserverPattern.theory.Observer02 state:0>>2
三、现实举例:观察执行线程的状态
1)subject
RunnableSubject封装RunnableObserver,在线程执行过程中,如果线程状态发生改变,就会把改变的信息封装为RunnableEvent发给RunnableObserver的update方法
public class RunnableSubject implements Runnable{
private RunnableObserver runnableObserver;
//new subject的时候传入观察者
public RunnableSubject(RunnableObserver runnableObserver){
this.runnableObserver=runnableObserver;
notifyRunnableObserver(new RunnableEvent(RunnableEvent.RunnableState.NEW,Thread.currentThread(),null));
}
//状态改变时调用这个方法来通知观察者做出相应响应
public void notifyRunnableObserver(RunnableEvent runnableEvent){
runnableObserver.update(runnableEvent);
}
@Override
public void run() {
notifyRunnableObserver(new RunnableEvent(RunnableEvent.RunnableState.RUNNING,Thread.currentThread(),null));
try{
System.out.println("正在运行....");
//人为的异常
int i=1/0;
}catch (Exception e){
notifyRunnableObserver(new RunnableEvent(RunnableEvent.RunnableState.ERROR,Thread.currentThread(),e));
}
notifyRunnableObserver(new RunnableEvent(RunnableEvent.RunnableState.DEAD,Thread.currentThread(),null));
}
}
2)observer
RunnObserver是观察者
public class RunnableObserver {
public void update(RunnableEvent runnableEvent){
System.out.println("+++++++++++++++++++++++++++++");
System.out.println("state:"+runnableEvent.getRunnableState());
System.out.println("thread:"+runnableEvent.getRunnableThread().getName());
if(runnableEvent.getRunableThrowable()!=null)
System.out.println("throwable:"+runnableEvent.getRunableThrowable().getMessage());
}
}
3)测试
测试类
public class Main {
public static void main(String[] args) {
RunnableObserver runnableObserver=new RunnableObserver();
RunnableSubject runnableSubject=new RunnableSubject(runnableObserver);
Thread t=new Thread(runnableSubject,"T");
t.start();
}
}
测试结果
+++++++++++++++++++++++++++++
state:NEW
thread:main
+++++++++++++++++++++++++++++
state:RUNNING
thread:T
正在运行....
+++++++++++++++++++++++++++++
state:ERROR
thread:T
throwable:/ by zero
+++++++++++++++++++++++++++++
state:DEAD
thread:T
四、总结
1)观察者模式还算一种应用比较广泛的编程思想,在现实中有很多例子,比如老师的电话改变了通知所有学生。再比如监听器的实现等待都有应用到观察者模式的思想
2)观察者模式很容易实现,只要知道那个是subject,哪个是observer,就可以很容易的实现