观察者模式
当一个对象状态发生变化时,能够自动通知其他关联对象,自动刷新对象状态
提供关联对象一种同步通信的手段,使某个对象与依赖它的其他对象之间保持状态同步
被观察者【主题】(subject)
具体被观察者(concrete subject)
观察者(observer)
具体被观察者(concrete observer)
观察者模式,是一种一对多的关系,即多个观察者监听一个主题。
/**
* 主题的接口 定义标准的方法
*/
public interface Subject {
public void addListener(Listener listener);
public void deleteListener(Listener listener);
public void notifyListener();
}
/**
* 实现主题的类,相当于图中的ConcretSubject A
*/
public class Lights implements Subject{
private ArrayList lights; //collection 用于保存 观察者的集合
private String whichLight;
private String currentLight = "green"; //记录当前 交通灯的状态
private int time; //记录交通灯持续的时间
public Lights(){
lights = new ArrayList();
}
//实现 添加一个观察者的操作
@Override
public void addListener(Listener listener){
lights.add(listener);
}
//实现删除一个观察者的操作
@Override
public void deleteListener(Listener listener){
int index = lights.indexOf(listener);
if( index != -1){
lights.remove(index);
}
}
//实现通知的机制 ,通知每一个观察者
public void notifyListener(){
int size = lights.size();
for(int i = 0; i < size; i++){
Listener listener = (Listener)lights.get(i);
listener.updateSignal(whichLight,time);
}
}
//更新主题状态数据的方法
public void setLight(String whichlight,int time){
this.whichLight = whichlight;
this.time = time;
//检查状态是否发生了变化
check();
this.currentLight = whichLight;
}
//实现检查状态的函数
private void check(){
if(! this.currentLight.equals(this.whichLight)){
notifyListener();
}
}
}
/**
* 定义观察者接口 声明更新方法
*/
public interface Listener {
public void updateSignal(String whichLight,int time);
}
/**
* 实现红色交通灯的观察者类,相当于图中国的ConcretObserver类
*/
public class RedLightListener implements Listener{
@Override
//模拟接收通知,更新状态
public void updateSignal(String whichLight, int time){
if(whichLight.equals("red")){
System.out.println("红灯亮了,禁止通行");
System.out.println("持续时间: "+time);
}
}
}
/**
* 演示设计模式---观察者模式的demo
*/
public class ObserverPattern {
public static void main(String[] args) {
// TODO code application logic here
//创建主题,被监听对象,通常是一个自身状态属性可变的类
Lights lights = new Lights();
//创建观察者实例
RedLightListener red = new RedLightListener();
//向主题注册三个观察者,监听变化
lights.addListener(red);
//手动的改变交通灯的状态
lights.setLight("red",30);
}
观察者模式典型应用
1、监听对象状态变化
2.发布者订阅者模型【外部事件被触发,邮件通知订阅者】
优点:
(1) 主题与观察者建立一个抽象的耦合而不是紧密的耦合,降低了耦合度;主题只需要维护一个抽象观察者的集合,无需了解具体观察者,使得可以有各种各样不同的观察者实现。
(2) 支持广播通信,主题会向所有已注册的观察者对象发送通知,简化了一对多系统设计的难度。
(3) 符合“开闭原则”,增加新的具体观察者无须修改原有代码,可拓展性高。
缺点:
(1) 如果主题有很多直接或者间接观察者,那么全部通知到会很耗时。
(2) 主题与观察者之间如果存在循环依赖,可能导致系统崩溃。