一、介绍
观察者模式常用于一对多的监听情景,并且被监听者可以实现监听者的回调,也就是说被监听者能够触发监听者的动作,该动作就是回调。
观察者模式的特点:
1.被观察者不知道具体的观察者是谁,只知道自己被观察了,并且在合适的时机进行广播,让感兴趣的观察者知道发生了什么事情。
2.观察者依赖于被观察者,被观察者不依赖于观察者,是单向关系,耦合程度不高。没有被观察者,观察者无法工作;没有观察者,被观察者该干啥干啥,因为被观察者本来就不清楚谁观察他,发广播是被观察的个人行为。
3.通常被观察者出现行为上的变化,需要观察者做出反馈。显然一般情况下观察者并不知道被观察者啥时候会有变化,因此该反馈是一种被动反馈,实现的是一种回调机制。
二、实现
1、自定义接口
被观察者
package com.swust.java.行为型模式.观察者模式x;
import java.util.ArrayList;
import java.util.List;
public class Subject {
// 所有观察者集合
protected List<Observer> list = new ArrayList<>();
public void register(Observer observer){
list.add(observer);
}
public void remove(Observer observer){
list.remove(observer);
}
// 通知所有的观察者更新状态
public void notifyAllObservers(){
for (Observer observer : list) {
observer.update(this);
}
}
}
/**
* 主题对象
* 被观察者
*/
class ConcreteSubject extends Subject{
private int state;
public int getState() {
return state;
}
public void setState(int state) {
this.state = state;
this.notifyAllObservers();
}
}
观察者
package com.swust.java.行为型模式.观察者模式x;
public interface Observer {
void update(Subject subject);
}
public class ObserverA implements Observer{
private int myState; // myState需要跟目标对象的state值保持一致
@Override
public void update(Subject subject) {
myState = ((ConcreteSubject)subject).getState();
}
public int getMyState() {
return myState;
}
public void setMyState(int myState) {
this.myState = myState;
}
}
客户端测试类
package com.swust.java.行为型模式.观察者模式x;
public class Client {
public static void main(String[] args) {
// 目标对象
ConcreteSubject subject = new ConcreteSubject();
// 创建多个观察者
ObserverA o1 = new ObserverA();
ObserverA o2 = new ObserverA();
ObserverA o3 = new ObserverA();
// 查看观察者状态
System.out.println(o1.getMyState());
System.out.println(o2.getMyState());
System.out.println(o3.getMyState());
// 将这三个观察者添加到subject对象的观察者队伍中
subject.register(o1);
subject.register(o2);
subject.register(o3);
// 改变subject的状态
subject.setState(3000);
// 查看观察者状态
System.out.println(o1.getMyState());
System.out.println(o2.getMyState());
System.out.println(o3.getMyState());
}
}
测试结果
0
0
0
3000
3000
3000
2、JDK接口
被观察者
package com.swust.java.行为型模式.观察者模式x.自带接口;
import java.util.Observable;
/**
* 目标对象
*/
public class ConcreteSubject extends Observable {
private int state;
public void set(int s){
state = s;// 目标状态改变
setChanged();// 表示目标对象已经做了更改
notifyObservers(state);// 通知所有观察者
}
public int getState() {
return state;
}
public void setState(int state) {
this.state = state;
}
}
观察者
package com.swust.java.行为型模式.观察者模式x.自带接口;
import java.util.Observable;
import java.util.Observer;
public class ObserverA implements Observer {
private int myState;
@Override
public void update(Observable o, Object arg) {
myState = ((ConcreteSubject)o).getState();
}
public int getMyState() {
return myState;
}
public void setMyState(int myState) {
this.myState = myState;
}
}
测试类
package com.swust.java.行为型模式.观察者模式x.自带接口;
public class Client {
public static void main(String[] args) {
// 目标对象
ConcreteSubject subject = new ConcreteSubject();
// 创建多个观察者
ObserverA o1 = new ObserverA();
ObserverA o2 = new ObserverA();
ObserverA o3 = new ObserverA();
// 将这三个观察者添加到subject对象的观察者队伍中
subject.addObserver(o1);
subject.addObserver(o2);
subject.addObserver(o3);
// 改变subject的状态
subject.set(666);
// 查看观察者状态
System.out.println(o1.getMyState());
System.out.println(o2.getMyState());
System.out.println(o3.getMyState());
}
}
执行结果
666
666
666