定义:对象间一种一对多的依赖关系,使得一个对象改变状态,则所有依赖于他的对象都会得到通知并被自动更新
使用场景:
- 关联行为场景。
- 事件多级触发场景
- 跨系统的消息交换场景。如消息队列,事件总线的处理机制。
应用举例:观察者订阅被观察者的状态,当被观察者状态改变的时候会通知所有订阅的观察者的过程。
关键代码:在抽象类里有一个 ArrayList 存放观察者们。
类图:
- Subject:抽象的被观察者,把所有观察者的引用保存在一个集合里,每个集合可以有任意数量的的观察者,提供一个接口,可以增加和删除观察者
- ConcreteSubject:具体的被观察者,实现抽象被观察者的方法
- Observer:抽象的观察者,定义一个更新接口(update方法),在被观察者更改是通知自己
- ConcreteObserver:具体的观察者,实现抽象观察者的方法
优点:
- 观察者和被观察者是抽象耦合的。
- 建立一套触发机制(订阅系统)。
缺点:
- 被观察者如果有很多观察者的话,通知是很花费时间的
- 被观察者只知道观察者反生了变化,不知道为啥发生变化。
- 被观察者和观察者如果有循环调用的话,程序会发生崩溃。
//创建观察者的抽象类
abstract class Observer{
public abstract void update(String msg);
}
//创建三个观察者
class firstObserver extends Observer{
@Override
public void update(String msg) {
// TODO 自动生成的方法存根
System.out.println(firstObserver.class.getName()+"收到了信息:"+msg);
}
}
class secondObserver extends Observer{
@Override
public void update(String msg) {
// TODO 自动生成的方法存根
System.out.println(secondObserver.class.getName()+"收到了信息:"+msg);
}
}
class thirdObserver extends Observer{
@Override
public void update(String msg) {
// TODO 自动生成的方法存根
System.out.println(thirdObserver.class.getName()+"收到了信息:"+msg);
}
}
class Subject{
ArrayList<Observer> observersList = new ArrayList<>();
public void setMsg(String msg) {
notifyAll(msg);
}
public void addAttach(Observer observer) {
observersList.add(observer);
}
//通知所有的观察者
private void notifyAll(String msg) {
// TODO 自动生成的方法存根
for(Observer observer :observersList) {
observer.update(msg);
}
}
}
主函数
public static void main(String[] args) {
// TODO 自动生成的方法存根
//创建三个观察者
firstObserver firstObserver = new firstObserver();
secondObserver secondObserver = new secondObserver();
thirdObserver thirdObserver = new thirdObserver();
//创建被观察者
Subject subject = new Subject();
subject.addAttach(firstObserver);
subject.addAttach(secondObserver);
subject.addAttach(thirdObserver);
subject.setMsg("我要更新信息");
}
运行结果
从运行结果来看,一旦被观察者(subject)有什么动作,观察者(observer)都会收到。