观察者模式是属于行为模式,观察者模式:定义对象间一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知自动更新。
概念可能有点抽象,我们来假设一个场景来理解一下,假如你正在看电视,当你正看得入神时, 有人突然告诉你说,厨房正在烧水,等水开了,你要记得关煤气。那么你会怎么做呢?
第一:在厨房里等着,直到水开了,把煤气关了,再来看电视。
第二:在烧水的锅子上做一个装置,当水一开了就会向你发出信息,你收到信息后就可以把煤气关了。
这两种方式,我相信大家肯定会选第二种的,因为节约时间,也没有耽误你去看电视。是不是很酷啊?那好,现在我们来看看怎么来做这样一个装置!为了形象一点,下面例子讲的不是锅子,而且来监控一个按钮。
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、如果在被监听者之间有循环依赖的话,被监听者会触发它们之间进行循环调用,导致系统崩溃。