观察者模式
观察者模式简单来说就是,被观察者做了一件事,观察他的人都知道了他做了什么事,而且每个观察者对他做的这件事做出相应的反应。
假如:我是被观察者,我的所有亲戚朋友都是观察者,我的亲戚朋友都观察着我,那么如果我在打球,我的所有亲戚朋友都能知道我在打球,而且他们可能会对我在打球做出不同的反应。
定义就是:定义对象间一种一对多的依赖关系,使得每当一个对象改变状态,则所有依赖于它的对象都会得到通知并被自动更新。也叫做发布订阅模式。
具体看看代码实现,简单明了:
这是被观察者的抽象类
import java.util.Vector; /** * * 被观察者 抽象类 * * @author July * @create 2013-7-2 下午10:17:36 * */ public abstract class Subject { // 定义一个观察者数组 private Vector<Observer> obsVector = new Vector<Observer>(); // 增加一个观察者 public void addObserver(Observer o) { obsVector.add(o); } // 删除一个观察者 public void delObserver(Observer o) { obsVector.remove(o); } // 通知所有观察者 public void notifyObservers() { for (Observer o : obsVector) { o.update(); } } }
这是观察者接口
/** * * 观察者 * * @author July * @create 2013-7-2 下午10:17:24 * */ public interface Observer { // 更新方法 public void update(); }
这是具体的被观察者,继承被观察者抽象类
/** * * 具体被观察者,继承被观察者抽象类 * * @author July * @create 2013-7-2 下午10:18:21 * */ public class ConcreteSubject extends Subject { public void doSomething() { System.out.println("被观察者开始做事!"); /* * do something * 通知所有观察者 */ super.notifyObservers(); } }
这是具体的观察者1
/** * * 具体观察者 * * @author July * @create 2013-7-2 下午10:21:21 * */ public class ConcreteObserver implements Observer { @Override public void update() { System.out.println("接收到信息,并进行处理!"); } }
这是具体的观察者2
/** * * 具体观察者 * * @author July * @create 2013-7-2 下午10:21:21 * */ public class ConcreteObserver1 implements Observer { @Override public void update() { System.out.println("接收到信息,并进行处理--------------!"); } }
这是测试类,注意:观察者是可以动态添加删除的
public class Client { /** * * * @author July * @create 2013-7-2 下午10:15:08 * * @param args */ public static void main(String[] args) { // 创建一个被观察者 ConcreteSubject subject = new ConcreteSubject(); // 定义一个观察者 Observer obs = new ConcreteObserver(); // 定义一个观察者 Observer obs1 = new ConcreteObserver1(); // 观察者观察被观察者 subject.addObserver(obs); subject.addObserver(obs1); // 观察者开始活动了 subject.doSomething(); } }
console输出:
被观察者开始做事!
接收到信息,并进行处理!
接收到信息,并进行处理--------------!
观察者模式的应用:
1、观察者和被观察者之间是抽象耦合,易于观察者和被观察者的扩展
2、简历一套触发机制,单一原则
观察者模式的使用场景:
1、关联行为场景。需要注意的是,关联行为是可拆分的,而不是“组合”关系。
2、事件多级触发场景
3、扩系统的消息交换场景,如消息队列的处理机制
观察者模式的注意事项:
1、广播链的问题:有无限级触发的时候,根据高手的经验,太多级触发不好控制,推荐做法是2级触发就好,比较好控制。
在JAVA种使用观察者模式,JAVA已经帮助我们做好了这种观察者模式,分别是JDK种的Observable(被观察者类)和Observer(观察者接口),实际使用中,创建被观察者接口(Inter),具体的被观察者继承Observable和实现Inter接口(自定义的接口),观察者只需要实现Observer接口即可。具体做法如下:
被观察者接口,我们自定义的
public interface Inter { public void haveBreakfast(); public void haveFun(); }
具体的被观察者(韩非子),继承Observable类和实现Inter接口
public class HanFeiZi extends Observable implements Inter { @Override public void haveBreakfast() { System.out.println("韩非子:开始吃饭了。。。"); // 通知所有观察者 super.setChanged(); super.notifyObservers("韩非子在吃饭"); } @Override public void haveFun() { System.out.println("韩非子:开始娱乐了。。。"); // 通知所有观察者 super.setChanged(); super.notifyObservers("韩非子在娱乐"); } }
具体的观察者,实现了Observer接口。。。
public class LiSi implements Observer { @Override public void update(Observable o, Object arg) { System.out.println("李斯:观察到李斯活动,开始向老板汇报了。。,"); reportToQinShiHuang(arg.toString()); System.out.println("李斯:汇报完毕。。。\n"); } private void reportToQinShiHuang(String reportContet) { System.out.println("李斯:报告,秦老板!韩非子有活动了---->" + reportContet); } }
测试类:
public class Client { /** * * * @author July * @create 2013-7-2 下午10:49:23 * * @param args */ public static void main(String[] args) { HanFeiZi inter = new HanFeiZi(); Observer lisi = new LiSi(); inter.addObserver(lisi); inter.haveBreakfast(); } }
Console输出,无论有多少个观察者都是一样。
韩非子:开始吃饭了。。。 李斯:观察到李斯活动,开始向老板汇报了。。, 李斯:报告,秦老板!韩非子有活动了---->韩非子在吃饭 李斯:汇报完毕。。。
以上代码拷过去就能运行。。。。。。。。。。。。
OK!大功告成,这就是观察者模式,该模式在开发灰常常用。把该模式结合实际的项目,应用到里面去,会取得意想不到的效果。。。。。。。。
参考:《设计模式之禅》一书