观察者模式
定义
多个对象之间存在一对多的依赖关系,当一个对象发生改变时,其他对象接收到通知并自动发生改变,也就是发布-订阅模式。
优点
- 降低目标与观察者之间的耦合,两者是属于抽象耦合的关系。符合依赖倒置原则。
- 目标与观察者之间建立一套触发机制
缺点
- 两者之间的依赖关系并没有完全解除,而且需要注意可能会出现循环引用。
- 当观察者对象特别多时,通知的发布会花费很多时间,影响程序的效率。
设计模式的结构
抽象目标类(被观察者)Subject:提供一个用于保存观察者对象的聚集类,以及相应的增加和删除观察者对象的方法,还有就是通知所有观察者的抽象方法。
抽象观察者-Observer:抽象类或者抽象接口, 包含了更新自己的抽象方法,当接收到通知后调用。
具体目标类 - Concrete Subject:实现抽象类中的目标方法,当具体目标的发生改变后,通知所有的注册者。
具体的观察者 - Concrete Observer: 实现抽象观察者中的抽象方法。
具体实现例子
抽象的观察者
public interface AbstractObserver {
//接收到通知后执行的方法
public void meth();
}
抽象的目标类
public abstract class AbstractSubject {
// 方便子类使用
protected List<AbstractObserver> observerList = new ArrayList<>();
public void add(AbstractObserver observer) {
this.observerList.add(observer);
}
public void remove(AbstractObserver observer) {
this.observerList.remove(observer);
}
public abstract void notice();
}
具体的目标类
public class ConcreteSubject extends AbstractSubject{
@Override
public void notice() {
System.out.println("发出通知!!!");
for (AbstractObserver obs:observerList) {
obs.meth();
}
System.out.println("通知结束");
}
}
具体的观察者
public class ConcreteObserver implements AbstractObserver{
@Override
public void meth() {
System.out.println("停止了摸鱼操作");
}
}
public class ConcreteObserver2 implements AbstractObserver{
@Override
public void meth() {
System.out.println("停止了看股票");
}
}
使用
public class SubjectObserverMain {
public static void main(String[] args) {
AbstractSubject subject = new ConcreteSubject();
AbstractObserver observer1 = new ConcreteObserver();
AbstractObserver observer2 = new ConcreteObserver2();
//加入订阅中
subject.add(observer1);
subject.add(observer2);
subject.notice();
}
}