定义:又称发布/订阅模式,观察者模式定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象。这个主题对象在状态发生变化时,会通知所有观察者对象,使他们能够自动更新自己。
使用场景:
当一个对象的改变需要通知其他对象时,且不知道有多少个对象需要等待改变。
结构:
抽象主题角色:把所有观察者对象的引用保存在一个集合中,每个抽象主题角色可以拥有多个观察者。提供一个可以新增和删除观察者的接口,还有一个通知观察者的接口。
具体主题角色:在具体主题内部状态改变时,给所有登记过的观察者发出通知。
抽象观察者角色:给具体观察者定义一个接口,在得到主题通知时更新自己的状态。
具体观察者角色:实现抽象观察者的接口,使本身的状态与主题的状态相协调。
实现例子
/**
* 抽象观察者
* @author JeffXu
* @since 2016-12-22
*/
public interface Observer {
//得到通知后更新自己的状态
void update();
}
/**
* 具体观察者对象
* 实现抽象观察者接口
* @author Jeff Xu
* @since 2016-12-22
*/
public class RealObserver implements Observer{
//订阅者名称
private String name;
public RealObserver(String name){
this.name = name;
}
//得到通知后更新自己的状态
public void update(){
System.out.println(this.name+"已经得到通知了!");
}
}
/**
* 抽象主题
* @author Jeff Xu
* @since 2016-12-22
*/
public interface Subject {
//持有观察者的引用列表
List<Observer> observerList = new ArrayList<Observer>();
/**
* 新增观察者
* @param observer
*/
void add(Observer observer);
/**
* 删除观察者
* @param observer
*/
void del(Observer observer);
/**
* 通知观察者接口
*/
void notifyObserver();
}
/**
* 具体主题,实现抽象主题的接口
* @author Jeff Xu
* @since 2016-12-22
*/
public class RealSubject implements Subject{
/**
* 新增观察者
* @param observer
*/
public void add(Observer observer){
Subject.observerList.add(observer);
}
/**
* 删除观察者
* @param observer
*/
public void del(Observer observer){
Subject.observerList.remove(observer);
}
/**
* 通知观察者接口
*/
public void notifyObserver(){
if(Subject.observerList != null && Subject.observerList.size() > 0){
for(Observer observer : Subject.observerList){
observer.update();
}
}
}
}
/**
* 测试类
* @author JeffXu
*
*/
public class ClientTest {
public static void main(String[] agrs){
Observer observer1 = new RealObserver("张三");
Observer observer2 = new RealObserver("李四");
Observer observer3 = new RealObserver("王五");
Subject subject = new RealSubject();
subject.add(observer1);
subject.add(observer2);
subject.add(observer3);
subject.notifyObserver();
System.out.println("================================删除王五后的通知================================");
subject.del(observer3);
subject.notifyObserver();
}
}
模式总结:
优点:解除了主题和具体观察者的耦合,让耦合的双方都依赖于抽象,而不是依赖于具体。
缺点:依赖关系并未完全解除,抽象通知者依旧依赖于抽象的观察者。