这篇文章是在前面的“
AWT事件总结”
博客文章的基础上总结的,其实前面的讲到AWT事件就是一个典型的
观察者模式使用场景(一个典型的应用示例),这样顺序的讲解目的是为了让我们能用AWT事件来深刻的
理解观察者模式。
下面讲解观察者模式:
那么在上面事件的调用过程中,为什么
监听器比如ActionListener实现类里面特定事件的方法会在事件发生的时候被调用呢?这里用到了一种模式,
观察者模式。
观察者模式(Observer):
观察者模式定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个猪蹄对象。这个主题对象在状态上发生变化时,会通知所有观察者对象,让
他们能够自动更新自己。
观察者模式的组成:
1、
抽象主题角色:把所有对观察者对象的引用保存在一个集合中,每个抽象主题角色都可以有任意数量的观察者。抽象主题提供一个
接口,可以增加和扇车观察者角色。一般用一个抽象类或接口来实现。
2、
抽象观察者角色:为所有具体的观察者定义一个接口,在得到主题的通知时更新自己。
3、
具体主题角色:在具体主题内部状态改变时,给所有登记过的观察者发出通知。具体主题角色通常用一个子类实现。
4、
具体观察者角色:该角色实现抽象观察者角色所要求的更新接口,以便使本身的状态与主题的状态相协调。如果需要,具体观察者角色可以保存一个指向具体主题角色的引用。通常用一个子类实现。
所谓的注册就是将一个观察者的对象应用存放到了主题里面去了么(一般是集合)。我们的方法最后肯定是主题来执行的呀,一定不是平白无故的自己就去执行了呀。永远没有自动调用这一回事,自动调用只是一种表面现象,是你还没有明白底层是怎么实现的。
下面的几个类是一个简单的典型的观察者模式程序:
class="java" name="code">package com.shengshiyuan.observer;
/**
* 抽象观察者角色
* 类: Watcher <br>
* 描述: TODO <br>
* 作者:
* 时间: Nov 5, 2013 5:36:14 PM
*/
public interface Watcher {
// 在得到主题的通知时更新自己
public void udpate(String str);
}
package com.shengshiyuan.observer;
/**
* 抽象主题角色
* 类: Watched <br>
* 描述: TODO <br>
* 作者:
* 时间: Nov 5, 2013 5:34:56 PM
*/
public interface Watched {
// 添加观察者
public void addWatcher(Watcher watcher);
// 移除观察者
public void removeWatcher(Watcher watcher);
// 通知观察者
public void notifyWatchers(String str);
}
package com.shengshiyuan.observer;
/**
* 具体观察者角色
* 类: ConcreteWatcher <br>
* 描述: TODO <br>
* 作者:
* 时间: Nov 5, 2013 5:51:47 PM
*/
public class ConcreteWatcher implements Watcher {
public void udpate(String str) {
System.out.println(str);
}
}
package com.shengshiyuan.observer;
import java.util.ArrayList;
import java.util.List;
/**
* 具体主题角色
* 类: ConcreteWatched <br>
* 描述: TODO <br>
* 作者:
* 时间: Nov 5, 2013 5:44:06 PM
*/
public class ConcreteWatched implements Watched {
// 一个主题会有多个观察者,多个观察者会放到一个集合里面,起到维护的作用。这个集合用来承载观察我的哪些观察者
private List<Watcher> list = new ArrayList<Watcher>();
public void addWatcher(Watcher watcher) {
list.add(watcher);
}
// 通知观察者
public void notifyWatchers(String str) {
for (Watcher watcher : list) {
watcher.udpate(str);
}
}
public void removeWatcher(Watcher watcher) {
list.remove(watcher);
}
}
package com.shengshiyuan.observer;
/**
* 测试类
* 类: Test <br>
* 描述: TODO <br>
* 作者:
* 时间: Nov 5, 2013 7:42:46 PM
*/
public class Test {
public static void main(String[] args) {
// 女为悦己者容(女孩有好多追求者)
Watched girl = new ConcreteWatched();
// 为其添加观察者
Watcher watcher1 = new ConcreteWatcher();
Watcher watcher2 = new ConcreteWatcher();
Watcher watcher3 = new ConcreteWatcher();
girl.addWatcher(watcher1);
girl.addWatcher(watcher2);
girl.addWatcher(watcher3);
girl.notifyWatchers("开心,爽");
// 女孩不喜欢第二个追求者,将他删除(移除观察者)
girl.removeWatcher(watcher2);
girl.notifyWatchers("爽!");
}
}