观察者模式

模式动机

建立一种对象与对象之间的依赖关系,一个对象发生改变时将自动通知其他对象,其他对象将相应做出反应。在此,发生改变的对象称为观察目标,而被通知的对象称为观察者,一个观察目标可以对应多个观察者,而且这些观察者之间没有相互联系,可以根据需要增加和删除观察者,使得系统更易于扩展,这就是观察者模式的模式动机。

模式定义

观察者模式(Observer Pattern):定义对象间的一种一对多依赖关系,使得每当一个对象状态发生改变时,其相关依赖对象皆得到通知并被自动更新。观察者模式又叫做发布-订阅(Publish/Subscribe)模式、模型-视图(Model/View)模式、源-监听器(Source/Listener)模式或从属者(Dependents)模式。观察者模式是一种对象行为型模式。

模式结构

模式结构

  • Subject(目标):目标又称为主题,它是指被观察的对象。在目标中定义了一个观察者集合,一个观察目标可以接受任意数量的观察者来观察,它提供一系列方法来增加和删除观察者对象,同时它定义了通知方法 notify()。目标类可以是接口,也可以是抽象类或具体类。
  • ConcreteSubject(具体目标):具体目标是目标类的子类,通常它包含有经常发生改变的数据,当它的状态发生改变时,向它的各个观察者发出通知;同时它还实现了在目标类中定义的抽象业务逻辑方法(如果有的话)。如果无须扩展目标类,则具体目标类可以省略。
  • Observer(观察者):观察者将对观察目标的改变做出反应,观察者一般定义为接口,该接口声明了更新数据的方法 update(),因此又称为抽象观察者。
  • ConcreteObserver(具体观察者):在具体观察者中维护一个指向具体目标对象的引用,它存储具体观察者的有关状态,这些状态需要和具体目标的状态保持一致;它实现了在抽象观察者Observer中定义的 update() 方法。通常在实现时,可以调用具体目标类的 attach() 方法将自己添加到目标类的集合中或通过 detach() 方法将自己从目标类的集合中删除。

模式实例

假设房间里安装了温度传感器,一旦温度达到限值,则屋内警报器会鸣叫,同时,大厦保安室的警报系统会报警,警报短信也会自动发给屋主,请模拟这一个过程。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
// Observer(观察者)
public interface Observer {
public void alarm();
}

// ConcreteObserver(具体观察者)
public class Indoor implements Observer {
public void alarm() {
System.out.println("屋内警报器鸣叫~~~");
}
}
public class SecurityRoom implements Observer {
public void alarm() {
System.out.println("大厦保安室警报系统报警~~~");
}
}
public class HouseOwner implements Observer {
public void alarm() {
System.out.println("警报短信自动发给屋主~~~");
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
// Subject(目标)
import java.util.Vector;
public class Subject {
// 使用Vector的原因:ArrayList线程异步,不安全;Vector线程同步,安全
private Vector<Observer> obs = new Vector<Observer>();
public void addObs(Observer o){
this.obs.add(o);
}
public void delObs(Observer o){
this.obs.remove(o);
}
public void notifyObs(){
for(Observer o:this.obs){
o.alarm();
}
}
}

// ConcreteSubject(具体目标)
public class Temperature extends Subject {
public void ReachLimit(){
System.out.println("温度达到限值!!!");
super.notifyObs();
}
}
1
2
3
4
5
6
7
8
9
10
11
12
// 客户端测试
public class Client {
public static void main(String[] args) {
Temperature temp = new Temperature();

temp.addObs(new Indoor());
temp.addObs(new SecurityRoom());
temp.addObs(new HouseOwner());

temp.ReachLimit();
}
}
文章目录
  1. 1. 模式动机
  2. 2. 模式定义
  3. 3. 模式结构
  4. 4. 模式实例

20160604-DesignPattern-11/

本页二维码