观察者模式

定义

多个对象之间存在一对多的依赖关系,当一个对象发生改变时,其他对象接收到通知并自动发生改变,也就是发布-订阅模式。

优点

  • 降低目标与观察者之间的耦合,两者是属于抽象耦合的关系。符合依赖倒置原则。
  • 目标与观察者之间建立一套触发机制

缺点

  • 两者之间的依赖关系并没有完全解除,而且需要注意可能会出现循环引用。
  • 当观察者对象特别多时,通知的发布会花费很多时间,影响程序的效率。

设计模式的结构

抽象目标类(被观察者)Subject:提供一个用于保存观察者对象的聚集类,以及相应的增加和删除观察者对象的方法,还有就是通知所有观察者的抽象方法。

抽象观察者-Observer:抽象类或者抽象接口, 包含了更新自己的抽象方法,当接收到通知后调用。

具体目标类 - Concrete Subject:实现抽象类中的目标方法,当具体目标的发生改变后,通知所有的注册者。

具体的观察者 - Concrete Observer: 实现抽象观察者中的抽象方法。

具体实现例子

抽象的观察者

  1. public interface AbstractObserver {
  2. //接收到通知后执行的方法
  3. public void meth();
  4. }

抽象的目标类

  1. public abstract class AbstractSubject {
  2. // 方便子类使用
  3. protected List<AbstractObserver> observerList = new ArrayList<>();
  4. public void add(AbstractObserver observer) {
  5. this.observerList.add(observer);
  6. }
  7. public void remove(AbstractObserver observer) {
  8. this.observerList.remove(observer);
  9. }
  10. public abstract void notice();
  11. }

具体的目标类

  1. public class ConcreteSubject extends AbstractSubject{
  2. @Override
  3. public void notice() {
  4. System.out.println("发出通知!!!");
  5. for (AbstractObserver obs:observerList) {
  6. obs.meth();
  7. }
  8. System.out.println("通知结束");
  9. }
  10. }

具体的观察者

  1. public class ConcreteObserver implements AbstractObserver{
  2. @Override
  3. public void meth() {
  4. System.out.println("停止了摸鱼操作");
  5. }
  6. }
  7. public class ConcreteObserver2 implements AbstractObserver{
  8. @Override
  9. public void meth() {
  10. System.out.println("停止了看股票");
  11. }
  12. }

使用

  1. public class SubjectObserverMain {
  2. public static void main(String[] args) {
  3. AbstractSubject subject = new ConcreteSubject();
  4. AbstractObserver observer1 = new ConcreteObserver();
  5. AbstractObserver observer2 = new ConcreteObserver2();
  6. //加入订阅中
  7. subject.add(observer1);
  8. subject.add(observer2);
  9. subject.notice();
  10. }
  11. }