观察者模式是对象的行为模式,又叫做发布—订阅模式(Publish/Subscribe)、模型—视图模(Model/View)、源—监听模式(Source/Listener)或从属者模式(Dependents)。
观察者模式定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象。这个主题对象在状态上发生变化时,会通知所有观察者对象,使他们能够自动更新自己。
- 根据上图可以看出,观察者聚集在被观察者的集合(比如List对象)中。
- 当被观察者发生变化时,会统一通知(调用update方法)每个观察自己的Observer。
- 观察者收到通知后,会更新自己。(被动更新)
类图及代码实现
未对被观察者进行抽象时
- 注意:Observer有个带参构造,用来设置自己的观察对象。
/*
* 被观察者
*/
import java.util.*;
public class Subject{
private int x;
private int y;
private List<Observer> list = new ArrayList<Observer>();
//添加观察者
public void add(Observer Obs){
list.add(Obs);
}
//通知观察者
public void Notify() {
for(Observer i: list) {
i.upDate(x, y);
}
}
//改变观察者内部数据
public void DataChange(int x, int y) {
this.x = x;
this.y = y;
Notify();
}
}
/*
* 观察者
*/
public class Observer{
int x;
int y;
public Observer(Subject s) {
s.add(this); //创建观察者对象时,就确定了自己要观察的对象。将自己添加进被观察者中
}
//更新观察的数据
public void upDate(int x, int y) {
this.x = x;
this.y = y;
}
}
/*
* 客户端
*/
public class Client {
public static void main(String[] args) {
//创建一个被观察者对象
Subject su = new Subject();
//创建一个观察者对象,并设置其要观察的对象
Observer obs1 = new Observer(su);
Observer obs2 = new Observer(su);
//被观察者发生改变
su.DataChange(7, 8);
//查看观察者是否更新
System.out.println(obs1.x);
System.out.println(obs2.x);
}
}
将观察者和被观察者都抽象化
[图片上传失败...(image-e7eb56-1552402936585)]
/*
* 被观察者基类
*/
abstract public class Subject {
private List<Observer> list = new ArrayList<Observer>();
public void add(Observer obs) {
list.add(obs);
}
public void Notify() {
for(Observer i: list) {
i.update();
}
}
}
/*
* 被观察者
*/
class ConcreteSubject extends Subject{
//被观察者的状态
private String stateA;
public void dataChange(String new_state) {
System.out.println("改变前的信息:"+stateA);
this.state = new_state;
System.out.println("改变后的信息:"+state);
this.Notify(); //当数据改变时,通知观察者们
}
}
/*
* 观察者抽象基类
*/
abstract public class Observer {
abstract public void update();
}
/*
* 观察者
*/
class ConcreteObserver extends Observer{
int x;
public ConcreteObserver(Subject s) {
//此处多态。以便能添加Observer的子类到
s.add(this);//创建观察者对象时,就确定了自己要观察的对象。将自己添加进被观察者中
}
//更新观察到的数据
@Override
public void update() {
System.out.println("观察的对象变化了");
}
}
/*
* 客户端
*/
public class Client {
public static void main(String[] args) {
//创建一个被观察者对象
ConcreteSubject cs = new ConcreteSubject();
//创建一个观察者对象,并设置自己要观察的对象
@SuppressWarnings("unused")
ConcreteObserver co1 = new ConcreteObserver(cs);
//改变观察者的信息
cs.dataChange("NO");
}
}