观察者模式又叫发布-订阅模式,当一个对象变化时,其它依赖该对象的对象都会收到通知,并且随着变化。对象之间是一种一对多的关系。
就像如果你订阅了“人民日报”,那每当此报纸出新版时,邮局的工作人员就会送一份到你的家里。此时,你就是“观察者”,观察的是“报纸”的动态。
使用场景和优缺点 |
使用场景:
(1)当一个对象的改变需要改变其它对象,而且它不知道具体有多少个对象有待改变时。
(2)一个抽象模型有两个方面,当其中一个方面依赖于另一个方面,这时用观察者模式可以将这两者封装在独立的对象中使它们各自独立地改变和复用。
(3)在项目中用到的场景,比如一个模块用于购票,另一个模块用于购票后发送短信通知购票成功,如此就可以使用观察者模式。
优点:
(1)观察者和被观察者之间抽象耦合。观察者模式容易扩展,被观察者只持有观察者集合,并不需要知道具体观察者内部的实现。
(2)对象之间的保持高度的协作。当被观察者发生变化时,所有被观察者都会通知到,然后做出相应的动作。
缺点:
(1)如果观察者太多,被观察者通知观察者消耗的时间很多,影响系统的性能。
(2)当观察者集合中的某一观察者错误时就会导致系统卡壳,因此一般会采用异步方式。
实现思路 |
(1)Subject类,通知者的抽象类,其内部有3个方法:
- 增加观察者
- 移除观察者
- 通知所有的观察者,即调用观察者的update()方法
(2)ConcreteSubject类,通知者的具体实现类。对抽象类中的方法进行了具体实现。
(3)Observer类,观察者的抽象类,其定义了一个公共方法update(),用于对自己进行更新。
(4)ConcreteObserver类,观察者的具体实现类。实现了update()方法。
类图

代码实现 |
Subject通知者抽象类:
public interface Subject {
/*增加观察者*/
public void add(Observer observer);
/*删除观察者*/
public void del(Observer observer);
/*通知所有的观察者*/
public void notifyObservers();
/*自身的操作*/
public void operation();
}
通知者实现类:
public abstract class AbstractSubject implements Subject {
private Vector<Observer> vector = new Vector<Observer>();
@Override
public void add(Observer observer) {
vector.add(observer);
}
@Override
public void del(Observer observer) {
vector.remove(observer);
}
@Override
public void notifyObservers() {
Enumeration<Observer> enumo = vector.elements();
while(enumo.hasMoreElements()){
enumo.nextElement().update();
}
}
}
public class MySubject extends AbstractSubject {
@Override
public void operation() {
System.out.println("update self!");
notifyObservers();
}
}
Observer观察者抽象类:
public interface Observer {
public void update();
}
观察者实现类:
public class Observer1 implements Observer {
@Override
public void update() {
System.out.println("observer1 has received!");
}
}
public class Observer2 implements Observer {
@Override
public void update() {
System.out.println("observer2 has received!");
}
}
测试类:
public class ObserverTest {
public static void main(String[] args) {
Subject sub = new MySubject();
sub.add(new Observer1());
sub.add(new Observer2());
sub.operation();
}
}
可见,观察者模式的作用就是解除耦合,让耦合的双方都依赖于抽象,而不是依赖于具体。从而使得各自的变化都不会影响另一边的变化。