作用
一个有状态的对象,当它的状态变化时需要通知多个关注该状态的对象
原理
- 所有观察者需要实现统一的一个接口,如: interface A 并实现 void a() 方法
- 被观察对象维护了一个观察者的列表 List<A> observers ,并提供增减观察者的方法
- 满足特定条件时,循环调用 observers 中每个观察者的 a() 方法 observer.a()
- 通常观察者也会维护一个被观察对象的引用,便于取消观察
- 观察者初始化完成后将自身注册到被观察者维护的观察者列表中。由观察者来执行注册的好处是当需要有新类型的观察者时,不需要修改被观察者的代码,符合开闭原则
基于Java提供的基类实现
RoomCapabilityCounter 记录一个房间当前人数,人数变化时,将信息通知给房间的多个管理员(RoomAdmin)
//被观察对象,记录一个房间的当前人数
public class RoomCapabilityCounter extends Observable {
// 描述当前人数
int count = 0;
public void addCount() {
// 当前人数+1
this.count++;
// 设置为已变化
setChanged();
// 调用通知的方法,会将自身作为参数传递,也可以指定传递额外的信息
notifyObservers(count);
}
@Override
public String toString() {
return "RoomCapabilityCounter{" +
"count=" + count +
'}';
}
}
//观察者,描述房间的管理人员
public class RoomAdmin implements Observer {
private String adminName;
// 持有被观察对象的引用
private RoomCapabilityCounter roomCounter;
public RoomAdmin(String adminName, RoomCapabilityCounter roomCounter) {
this.adminName = adminName;
this.roomCounter = roomCounter;
}
// 初始化完成,将自身注册到被观察者的观察者列表
public void startWork() {
roomCounter.addObserver(this);
}
@Override
public void update(Observable o, Object arg) {
// counter为被观察对象,arg 为notifyObservers()方法传递的值
RoomCapabilityCounter counter = (RoomCapabilityCounter) o;
System.out.println(adminName + "人数增加,当前人数:" + arg);
}
}
// 运行示例
public class Main {
public static void main(String[] args) {
RoomCapabilityCounter roomCapabilityCounter = new RoomCapabilityCounter();
RoomAdmin roomAdmin1 = new RoomAdmin("管理员1", roomCapabilityCounter);
RoomAdmin roomAdmin2 = new RoomAdmin("管理员2", roomCapabilityCounter);
RoomAdmin roomAdmin3 = new RoomAdmin("管理员3", roomCapabilityCounter);
roomAdmin1.startWork();
roomAdmin2.startWork();
roomAdmin3.startWork();
roomCapabilityCounter.addCount();
roomCapabilityCounter.addCount();
roomCapabilityCounter.addCount();
}
}