观察者模式--Observer

观察者模式是属于行为模式,观察者模式:定义对象间一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知自动更新。

概念可能有点抽象,我们来假设一个场景来理解一下,假如你正在看电视,当你正看得入神时, 有人突然告诉你说,厨房正在烧水,等水开了,你要记得关煤气。那么你会怎么做呢?

第一:在厨房里等着,直到水开了,把煤气关了,再来看电视。

第二:在烧水的锅子上做一个装置,当水一开了就会向你发出信息,你收到信息后就可以把煤气关了。

这两种方式,我相信大家肯定会选第二种的,因为节约时间,也没有耽误你去看电视。是不是很酷啊?那好,现在我们来看看怎么来做这样一个装置!为了形象一点,下面例子讲的不是锅子,而且来监控一个按钮。

public class Observer {
    public static void main(String[] args) {
        Button btn = new Button("按钮");

        // 为按钮添加监听器
        btn.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                System.out.println(e.getName() + "被点击");
            }
        });

        // 模拟点击事件
        btn.click();
    }
}
class Button {
    private String name = null;
    private List<ActionListener> actionlisteners = new ArrayList<ActionListener>();

    public Button(String name) {
        this.name = name;
    }
    //把监听器放到list中
    public void addActionListener(ActionListener e) {
        actionlisteners.add(e);
    }
    
    //点击事件
    public void click() {
        ActionEvent e = new ActionEvent(this.name);
        for (int i = 0; i < actionlisteners.size(); i++) {
            ActionListener l = actionlisteners.get(i);
            l.actionPerformed(e);
        }
    }
}

/*
 * 监听器接口
 */
interface ActionListener {
    public void actionPerformed(ActionEvent e);
}

/*
 * 事件源类
 */
class ActionEvent {
    private String name;

    public ActionEvent(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }
}

  来看一下整个程序运行的过程,首先,实例化了一个按钮,在这个按钮上加了一个监听器,加了之后则在Button这个类中的actionlisteners里添加一个监听器,当click()方法促发后,则在main方法中这个监听器的实现也就运行了!很简单吧?

  好了现在我们来分析一下什么情况下才会用到这种模式呢?

第一:一个方面(通常是多的那一方)依赖于另一个方面(通常是少的那一方)的变化;

第二:被监听的对象不知道被多少对象监听时,当被监听对象发生变化时对外广播;

观察者模式的优点:

1、被监听对象不需要了解是谁在监听,那些监听的对象只要实现一个共同的接口就可以了!所以被监听者和监听者没有紧密联在一起!

2、被监听的对象只要广播就可以让监听者做出相应的响应。

观察者模式的缺点:

  1、所有的监听器都是放在一个list中,大家想想如果被监听对象有大量的监听器存在,那当其中一个监听器响应了就要去list查找,这肯定就会影响一定的效率。

  2、如果在被监听者之间有循环依赖的话,被监听者会触发它们之间进行循环调用,导致系统崩溃。

posted @ 2012-07-04 16:43  何长春  阅读(145)  评论(0编辑  收藏  举报