设计模式系列之----观察者模式
观察者模式是一个广播机制的基础,实现1对N的联动,当1发生变化,N跟着相应变化,由此衍生了发布订阅模式,其方式分两种,①强制推送:当1发生变化,强制N也跟着发生变化,②拉的方式,即N方可以自己决定是否接收,只有当N这方有需要时才去获取最新的,不然就算1方变化,N这方也不更新。
观察者接口和具体实现类:
/**
*观察者接口
*/
public interface Observer {
void update(Subject subject);//观察者接收一个推送过来的主题
}
//============================
/**
*观察者具体实现类
*/
public class ObserverImpl implements Observer {
private int state; //拥有与主体一致的状态,用于接收订阅的主题内容
public int getState() {
return state;
}
public void setState(int state) {
this.state = state;
}
@Override
public void update(Subject subject) {
this.state=((ConcreteSubject)subject).getState();//在具体观察者中进行同步状态更新
}
}
主题基类和主题具体类
/**
* 主体的基类,定义了一些公用方法,没有具体主题,也可以定义成抽象类
*/
public class Subject {
public List<Observer> list=new ArrayList<Observer>();//在主体方定义一个容器存放注册的观察者
public void registerObserver(Observer obs){
list.add(obs);//注册观察者,即把需要订阅的观察者加进容器中
}
public void removeObserver(Observer obs){
list.remove(obs);//移除观察者
}
//主题发生变化时,通知所有观察者进行更新
public void notifyAllObservers(List<Observer> list){
for (Observer observer : list) {
observer.update(this);
}
}
}
//=================================================
/**
*有具体主题的子类
*/
public class ConcreteSubject extends Subject {
private int state;//模拟一个具体主题
public int getState() {
return state;
}
public void setState(int state) {
this.state = state;
this.notifyAllObservers(list);//此步为关键,当主题发生变化时,主题中注册的观察者的状态也跟着进行更新
}
}
客户端调用:
public static void main(String[] args) {
ConcreteSubject concreteSubject = new ConcreteSubject();//目标主题,发布者
ObserverImpl observer1=new ObserverImpl();
ObserverImpl observer2=new ObserverImpl();
ObserverImpl observer3=new ObserverImpl();
concreteSubject.registerObserver(observer1);//注册观察者
concreteSubject.registerObserver(observer2);
concreteSubject.registerObserver(observer3);
concreteSubject.setState(1000);//目标主题状态为1000
System.out.println(observer1.getState());
System.out.println(observer2.getState());
System.out.println(observer3.getState());//观察者的值也都为1000
concreteSubject.setState(2000);//目标主题状态值发生改变
System.out.println(observer1.getState());
System.out.println(observer2.getState());
System.out.println(observer3.getState());//观察者的值也改为2000
}
以上代码是自己实现的观察者模式,实际上JavaSE中已经为我们提供了实现观察者模式的基础,java.util.Observable类和java.util.Observer接口,通过这两个对象可以方便的实现观察者模式,java.util.Observable相当于上面定义的Subject,Observable中定义好了一些常用的方法来添加观察者,移除观察者等,观察者只要实现Observer接口就具有观察者身份,可以被添加进来。
/**
* 继承JDK的Observable类实现主题
*/
public class ConcreteSubject extends Observable{
private int state;
public int getState() {
return state;
}
public void setState(int state) {
this.state = state;
super.setChanged();//当次属性发生改变时,调用基类的setChanged()方法表示当前观察者有改变,
//主要改变super.hasChanged()方法返回值,观察者可以通过此值判断目标对象是否已改变
super.notifyObservers(this.state);//把当前发生改变的对象通知各个观察者
}
}
//===================================================
/**
*实现JDK的观察者接口,实现更新方法
*/
public class ObserverImpl implements Observer {
private int state;
public int getState() {
return state;
}
public void setState(int state) {
this.state = state;
}
@Override
public void update(Observable o, Object obj) {
setState(((ConcreteSubject)o).getState());
//this.state =Integer.parseInt((String)obj);//也可以直接通过传递过来的参数赋值
}
}
//==================================================
public static void main(String[] args) {
ConcreteSubject subject=new ConcreteSubject();
ObserverImpl observer1=new ObserverImpl();
ObserverImpl observer2=new ObserverImpl();
ObserverImpl observer3=new ObserverImpl();
subject.addObserver(observer1);
subject.addObserver(observer2);
subject.addObserver(observer3);
subject.setState(10);
System.out.println(observer1.getState());
System.out.println(observer2.getState());
System.out.println(observer3.getState());//观察者的值也都为1000
subject.setState(2000);//目标主题状态值发生改变
System.out.println(observer1.getState());
System.out.println(observer2.getState());
System.out.println(observer3.getState());//观察者的值也改为2000
}
JavaEE中监听器就使用的是观察者模式

浙公网安备 33010602011771号