Java的API中有两组接口类是用来写观察者模式用的,分别是java.util.Observable、java.util.Observer和java.util.EventListener、Java.util.EventObject。本文并没有直接使用到这些API,而是自定义一套观察者模式中相关的接口类,且选取一个日常生活中常见的一个事件来说明观察者模式的使用。
现实场景:有一名店(Shop),为了财物安全起见,除了在店内装了摄像头(Camera)来监控店内的总人数外,还聘请了一些门卫(Camera)守在店门口,对来访的客人进行实名登记,即客人进入时要记名,客人出店时也要记录其离去。
//Watcher接口:
packagesimple.observer;
/** *//**
* 观察者接口
*@authorrongxinhua
*
*/
publicinterfaceWatcher
{
/** *//**
* (接收到通知后,)观察者采取行动
*@parammsg
*/
publicvoidtakeAction(Object
msg);
}
//Watchable类:
packagesimple.observer;
importjava.util.HashSet;
importjava.util.Set;
/** *//**
* "被观察对象" 的父类
*@authorrongxinhua
*
*/
publicclassWatchable
{
privateSetwatcherSet=newHashSet();
/** *//**
* 通知观察者
*@paramparams 通知的信息数组
*/
protectedvoidnotifyWatchers(Object
params)
{
for(Watcher watcher : watcherSet)
{
watcher.takeAction(params);//观察者采取行动
}
}
/** *//**
* 增加观察者
*@paramwatcher
*/
protectedvoidaddWatcher(Watcher watcher)
{
watcherSet.add(watcher);
}
/** *//**
* 移除观察者
*@paramwatcher
*/
protectedvoidremoveWatcher(Watcher watcher)
{
watcherSet.remove(watcher);
}
}
//Shop类,继承了Watchable类,Shop内有什么动静,会通过调用父类的notifyWatcher()方法通知观察者。
packagesimple.observer;
importjava.util.HashSet;
importjava.util.Set;
/** *//**
* 店类,可被观察的
*@authorrongxinhua
*
*/
publicclassShopextendsWatchable
{
staticString IN="in";//进入
staticString OUT="out";//出去
SetpersonSet=newHashSet();
intpcount=0;//店内总人数
/** *//**
* 来访登记
*@paramname
*/
publicvoidcomeIn(String name)
{
personSet.add(name);
pcount=personSet.size();
notifyWatchers(IN, name, pcount);//通知观察者
}
/** *//**
* 出店登记
*@paramname
*/
publicvoidgetOut(String name)
{
personSet.remove(name);
pcount=personSet.size();
notifyWatchers(OUT, name, pcount);//通知观察者
}
}
//Guard(门卫类)和Camera(摄像头类)都属于本例中的观察者,负责观察店内外的动静,
packagesimple.observer;
/** *//**
* 门卫(保安)类
*@authorrongxinhua
*
*/
publicclassGuardimplementsWatcher
{
privateString name;//门卫姓名
publicGuard()
{}
publicGuard(String name)
{
this.name=name;
}
@Override
publicvoidtakeAction(Object
msg)
{
if(msg[0].equals("in"))
{
System.out.println(this.name+"向管理处汇报:“"+msg[1]+"”已进入本店!");
}
elseif(msg[0].equals("out"))
{
System.out.println(this.name+"向管理处汇报:“"+msg[1]+"”已走出本店!");
}
}
}
packagesimple.observer;
/** *//**
* 摄像头类
*@authorrongxinhua
*
*/
publicclassCameraimplementsWatcher
{
privateintid;//摄像头编号
publicCamera(intid)
{
this.id=id;
}
@Override
publicvoidtakeAction(Object
msg)
{
System.out.println("摄像头"+id+"号监测到现在店内总人数为"+msg[2]+"人");
}
}
//测试类代码:
packagesimple.observer;
publicclassTest02
{
/** *//**
*@paramargs
*/
publicstaticvoidmain(String[] args)
{
Shop shop=newShop();
//添加摄像头1号
Camera camera=newCamera(1);
shop.addWatcher(camera);
//添加门卫一号
Guard guard1=newGuard("门卫一号");
shop.addWatcher(guard1);
//来访登记、出门登记
shop.comeIn("BlogJava");
shop.comeIn("JavaEye");
shop.getOut("BlogJava");
//移除门卫一号,派他去做别的事
shop.removeWatcher(guard1);
//进入无人观察状态,随进随出
shop.comeIn("CSDN");
shop.getOut("JavaEye");
shop.comeIn("心梦帆影");
//添加门卫二号
Guard guard2=newGuard("门卫二号");
shop.addWatcher(guard2);
//来访登记,出门登记
shop.comeIn("容新华");
shop.getOut("CSDN");
}
}
运行测试类,结果如下:
1
门卫一号向管理处汇报:“BlogJava”已进入本店!2
摄像头1号监测到现在店内总人数为1人3
门卫一号向管理处汇报:“JavaEye”已进入本店!4
摄像头1号监测到现在店内总人数为2人5
门卫一号向管理处汇报:“BlogJava”已走出本店!6
摄像头1号监测到现在店内总人数为1人7
摄像头1号监测到现在店内总人数为2人8
摄像头1号监测到现在店内总人数为1人9
摄像头1号监测到现在店内总人数为2人10
门卫二号向管理处汇报:“容新华”已进入本店!11
摄像头1号监测到现在店内总人数为3人12
门卫二号向管理处汇报:“CSDN”已走出本店!13
摄像头1号监测到现在店内总人数为2人
本文原创,转载请注明出处,谢谢!http://www.blogjava.net/rongxh7(心梦帆影JavaEE技术博客)
posted on 2009-12-20 19:37 心梦帆影 阅读(2912) 评论(3) 编辑 收藏