1、定义:源于GOF的Design Patterns一书。
Define a one-to-many dependency between objects so that when oneobject changes
state, all its dependents are notified and updatedautomatically.
大概的意思就是说:一对多的对象之间,当一个对象的数据/状态发生变化时,所有与之关联的对象都会得到通知,并自动更新。(笔者英文不好)
2、为什么要使用观察者模式?
下面举个例子。全国各个地方的气象台,他们都是根据国家气象监测局监测到的气象信息数据进行播报。
这是个简单的例子,监测局是一个具体的主题,各个地方气象台充当着各个具体的观察者,他们要根据监测局的信息变化来进行实时的气象发布,播报。也就是说,监测局得到信息发生改变,各个地方的气象台就得得到通知并作出响应。
下面我们来看一下具体的类图
主题<接口>:规定了具体主题需要实现的方法,管理观察者以及通知观察者的方法
观察者<接口>:规定了具体观察者需要实现的方法,收到通知作出响应的方法
监测局<具体实现类>:实现具体管理和通知逻辑
气象台<具体实现类>:实现收到通知的具体响应操作
3、简单代码实现
/*
* 主题接口
*/
public interface Subject {
void addObserver(Observer o);
void delectObserver(Observer o);
void notifyObserver();
//拉数据的是形式获取数据
String getData();
}
/*
* 观察者接口
*/
public interface Observer {
void update();
}
import java.util.ArrayList;
import java.util.List;
/*
* 监测局
*/
public class Monitor implements Subject{
//观察者list
List<Observer> observerList;
//监测到的气象信息
String weatherData;
public Monitor() {
observerList = new ArrayList<Observer>();
weatherData = "";
}
/*
* 增加观察者
*/
public void addObserver(Observer o) {
if(!observerList.contains(o)){
observerList.add(o);
}
}
/*
* 移除观察者
*/
public void delectObserver(Observer o) {
if(observerList.contains(o)) {
observerList.remove(o);
}
}
/*
* 通知观察者更新数据
*/
public void notifyObserver() {
for (int i = 0; i < observerList.size(); i++) {
Observer o = observerList.get(i);
o.update();
}
}
/*
* 监测的方法(简单举例子,实际肯定没这么简单)
*/
public void setWeatherData(String data) {
weatherData = data;
notifyObserver();
}
/*
* 获取数据
*/
public String getData() {
return weatherData;
}
}
/*
* 气象台1
*/
public class Observatory1 implements Observer{
String name;
Subject subject;
public Observatory1(String name, Subject subject) {
this.name = name;
this.subject = subject;
subject.addObserver(this);
}
public void update() {
System.out.println("大家好,我是"+name+",今天天气:"+subject.getData());
}
}
/*
* 气象台2
*/
public class Observatory2 implements Observer{
String name;
Subject subject;
public Observatory2(String name, Subject subject) {
this.name = name;
this.subject = subject;
subject.addObserver(this);
}
public void update() {
System.out.println("大家好,我是"+name+",今天天气:"+subject.getData());
}
}
public class Main {
public static void main(String[] args) {
//监测局实例
Monitor monitor = new Monitor();
//气象局实例
Observatory1 o1 = new Observatory1("广州台", monitor);
Observatory2 o2 = new Observatory2("深圳台", monitor);
//监测局监测天气
monitor.setWeatherData("晴天");
}
}
运行结果:
4、观察者模式获取数据的两种方式
⑴、推数据,也具体主题就是在通知的时候将数据参数形式传到具体观察者中,观察者再进行处理
⑵、拉数据,具体主题提供相关的数据获取方法,可以是部分的,也可以是整体的,具体观察者收到通知后,在响应操作中调用具体主题提供的方法获取数据(举栗子:上述的例子中,气象台1只关心天气状况,气象台2只关心气温变化,监测局就必须提供返回不同数据的多个方法,供具体气象台调用)
5、上面的例子写得比较简单,只是供理解观察者设计模式的思想,并不是说什么编程,当然笔者也是个菜鸟~
实际编程当中很少会使用上面那种自定义的主题和观察者,而是使用Java util类库提供了Obserable类和Observer接口。这样有什么优点呢,笔者认为这是有利于系统复用。
相关的请转查Java官方Api。
6、文章写得简单粗暴,算是学习笔记,仅供入门学习参考。(深入等笔者日后再续)