一、定义与组成部分
1. 定义
Observer)模式 又名发布-订阅(Publish/Subscribe)模式。GOF 给观察者模式如下定义:
1.
2.
Observer)模式 又名发布-订阅(Publish/Subscribe)模式。GOF 给观察者模式如下定义:
3.
——单一职责原则。系统的每个对象应该将重点放在问题域中的离散抽象上。因此理想的情况下,一个对象只做一件事情。这样在开发中也就带来了诸多的好处:提供了重用性和维护性,也是进行重构的良好的基础。
2. 组成部分
Subject):目标角色知道它的观察者,可以有任意多个观察者观察同一个目标。并且提供注册和删除观察者对象的接口。目标角色往往由抽象类或者接口来实现。
Observer):为那些在目标发生改变时需要获得通知的对象定义一个更新接口。抽象观察者角色主要由抽象类或者接口来实现。
Concrete Subject):将有关状态存入各个Concrete Observer 对象。当它的状态发生改变时, 向它的各个观察者发出通知。
Concrete Observer):存储有关状态,这些状态应与目标的状态保持一致。实现Observer 的更新接口以使自身状态与目标的状态保持一致。在本角色内也可以维护一个指向Concrete Subject 对象的引用。
Subject 这个抽象类中,提供了上面提到的功能,而且存在一个通知方法:notify。
Subject 和ConcreteSubject 之间可以说是使用了模板模式(这个模式真是简单普遍到一不小心就用到了)。
update 方法来调整观察者的状态。
二、实现观察者模式
MySubject类就是我们的主对象,Observer1和Observer2是依赖于MySubject的对象,当MySubject变化时,Observer1和Observer2必然变化。
AbstractSubject类中定义着需要监控的对象列表,可以对其进行修改:增加或删除被监控对象,且当MySubject变化时,负责通知在列表内存在的对象。
Observer接口:
public interface Observer {
public void update();
}
Observer1
public class Observer1 implements Observer {
@Override
public void update() {
System.out.println("observer1 接收到了!");
}
}
Observer2
public class Observer2 implements Observer{
@Override
public void update() {
System.out.println("observer2 接收到了!");
}
}
Subject接口
public interface Subject {
/**
* 增加观察者
*
* @param observer
*/
public void add(Observer observer);
/**
* 删除观察者
* @param observer
*/
public void del(Observer observer);
/**
* 通知所有的观察者
*/
public void notifyObservers();
/**
* 自身的操作
*/
public void operation();
}
Subject实现类
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();
}
}
@Override
public void operation() {
}
}
MySubject类
public class MySubject extends AbstractSubject {
@Override
public void operation() {
System.out.println("主对象的状态发生了改变!");
notifyObservers();
}
}
public class Test {
public static void main(String[] args) {
Subject subject = new MySubject();
subject.add(new Observer1());
subject.add(new Observer2());
subject.operation();
}
}
三、 总结
1.观察者模式 主要解决了什么问题?
2.如何解决?
3.观察者模式 何时使用?
4.观察者模式 的优缺点
① 观察者和被观察者是抽象耦合的。
② 建立一套触发机制。
① 如果一个被观察者对象有很多的直接和间接的观察者的话,将所有的观察者都通知到会花费很多时间。
②如果在观察者和观察目标之间有循环依赖的话,观察目标会触发它们之间进行循环调用,可能导致系统崩溃。
③ 观察者模式没有相应的机制让观察者知道所观察的目标对象是怎么发生变化的,而仅仅只是知道观察目标发生了变化。
5.观察者模式 的使用场景
A对象的行为将影响B对象,B对象的行为将影响C对象……,可以使用观察者模式创建一种链式触发机制。
6.观察者模式 的注意事项
① JAVA 中已经有了对观察者模式的支持类。
② 避免循环引用。
③ 如果顺序执行,某一观察者错误会导致系统卡壳,一般采用异步方式。