观察者模式是使用频率最高的设计模式之一,它用于建立一种对象与对象之间的依赖关系,一个对象发生改变时将自动通知其他的对象,其他对象将相应作出反应。
以下是观察者模式的结构图:
观察者模式中,Subject通过调用attach()添加一个观察者,当自身状态改变时,通过notify()通知所有的观察者。
看起来是不是很熟悉呢,是的,我们经常在一个JButton对象上调用addActionListener(),然后JButton被点击时就调用了listener里面的actionPerformed()了,可以尝试对一个button添加多个listener,看看listener里面的actionPerformed()是不是一一被调用了呢。这就是观察者模式的应用。
下面看一个简单有趣的例子:
public class ObserverTest {
public static void main(String[] args) {
// TODO Auto-generated method stub
ConcreteAllyControlCenter acc = new ConcreteAllyControlCenter("A联盟");
Observer o1 = new Player("甲");
Observer o2 = new Player("乙");
Observer o3 = new Player("丙");
acc.join(o1);
acc.join(o2);
acc.join(o3);
o1.beAttacked(acc);
}
}
//观察者接口
interface Observer{
public String getName();
public void setName(String name);
public void help();
public void beAttacked(AllyControlCenter acc);
}
//玩家,观察战队中心
class Player implements Observer{
private String name;
public Player(String name){
this.name = name;
}
@Override
public String getName() {
// TODO Auto-generated method stub
return name;
}
@Override
public void setName(String name) {
// TODO Auto-generated method stub
this.name = name;
}
//当其他队员被攻击时,去帮助他
public void help() {
// TODO Auto-generated method stub
System.out.println("坚持住。。。"+name+"来支援你了");
}
//当自己被攻击时,通知战队中心
public void beAttacked(AllyControlCenter acc) {
// TODO Auto-generated method stub
System.out.println("请求支援");
acc.notifyObserver(name);
}
}
abstract class AllyControlCenter{
protected String allyName;
protected ArrayList<Observer> plays = new ArrayList<Observer>();
public void setAllyName(String allyName){
this.allyName = allyName;
}
public String getAllyName(){
return this.allyName;
}
public void join(Observer o){
System.out.println(o.getName()+"加入战斗");
plays.add(o);
}
public void quit(Observer o){
System.out.println(o.getName()+"退出战斗");
plays.remove(o);
}
public abstract void notifyObserver(String name);
}
//战队中心,负责派发支援
class ConcreteAllyControlCenter extends AllyControlCenter{
public ConcreteAllyControlCenter(String allyName){
System.out.println(allyName+"战队组建成功");
this.allyName = allyName;
}
//通知所有队员去支援被攻击者
public void notifyObserver(String name) {
// TODO Auto-generated method stub
int length = this.plays.size();
for(int i = 0;i < length;i++){
Observer o = this.plays.get(i);
if(!o.getName().equalsIgnoreCase(name)){
o.help();
}
}
}
}
JDK对观察者模式提供了支持,java.util包下有两个类:Observer,Observable,但是JDK自己并没有使用这两个类。
很多的swing组件都使用了观察者模式,可以参看:看JSlider的jdk源码学观察者模式