一、定义与组成部分
- 定义
观察者(Observer)模式 又名发布-订阅(Publish/Subscribe)模式。GOF 给观察者模式如下定义:
一、定义与组成部分 -
定义
-
观察者(Observer)模式 又名发布-订阅(Publish/Subscribe)模式。GOF 给观察者模式如下定义:
-
定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新。
面向对象设计的一个重要原则——单一职责原则。系统的每个对象应该将重点放在问题域中的离散抽象上。因此理想的情况下,一个对象只做一件事情。这样在开发中也就带来了诸多的好处:提供了重用性和维护性,也是进行重构的良好的基础。 -
组成部分
观察者模式由以下几部分组成:
抽象目标角色(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 {br/>@Override
public void update() {
System.out.println("observer1 接收到了!");
}
}
实现类:Observer2
public class Observer2 implements Observer{br/>@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() {