Java的API中有两组接口类是用来写观察者模式分别是java.util.Observable、java.util.Observer。
现实场景:有一名店(Shop),为了财物安全起见,除了在店内装了摄像头(Camera)来监控店内的总人数外,还聘请了一些门卫(Guard)守在店门口,对来访的客人进行实名登记,即客人进入时要记名,客人出店时也要记录其离去。
观察者(Camera)
package observer;
import java.util.Observable;
import java.util.Observer;
/**
* @author yingmu
* @version 2011-3-16 下午05:29:10
*/
public class Camera implements Observer {
private int id;
public Camera(int id) {
this.id = id;
}
@Override
public void update(Observable o, Object obj) {
Message message = (Message) obj;
if (message.getAcutinType().equals("in")) {
System.out.println("摄像头" + this.id + "号,监控到1个人进入商店,当前店内有"
+ message.getTotal() + "个人");
} else if (message.getAcutinType().equals("out")) {
System.out.println("摄像头" + this.id + "号,监控到个人离开商店,当前店内有"
+ message.getTotal() + "个人");
}
}
}
观察者(Guard)
package observer;
import java.util.Observable;
import java.util.Observer;
/**
* @author yingmu
* @version 2011-3-16 下午05:28:53
*/
public class Guard implements Observer {
private String name;
public Guard(String name) {
this.name = name;
}
@Override
public void update(Observable o, Object obj) {
Message guidMessage = (Message) obj;
if (guidMessage.getAcutinType().equals("in")) {
System.out.println("保安" + this.name + "汇报:"
+ guidMessage.getCustomer() + "进入商店");
} else if (guidMessage.getAcutinType().equals("out")) {
System.out.println("保安" + this.name + "汇报:"
+ guidMessage.getCustomer() + "离开商店");
}
}
public String toString() {
return name;
}
}
被观察者(Shop)
package observer;
import java.util.HashSet;
import java.util.Observable;
import java.util.Set;
/**
* @author yingmu
* @version 2011-3-16 下午05:28:35
*/
public class Shop extends Observable {
private static final String IN = "in";
private static final String OUT = "out";
private Set<String> personSet = new HashSet<String>();
public void comeIn(String name) {
personSet.add(name);
Message message = new Message();
message.setAcutinType(IN);
message.setCustomer(name);
message.setTotal(personSet.size());
setChanged();
notifyObservers(message); // 通知观察者
}
public void getOut(String name) {
personSet.remove(name);
Message message = new Message();
message.setAcutinType(OUT);
message.setCustomer(name);
message.setTotal(personSet.size());
setChanged();
notifyObservers(message); // 通知观察者
}
}
消息体(Message)
package observer;
/**
* @author yingmu
* @version 2011-3-16 下午05:45:01
*/
public class Message {
private String acutinType;
private String customer;
private int total;
public int getTotal() {
return total;
}
public void setTotal(int total) {
this.total = total;
}
public String getAcutinType() {
return acutinType;
}
public void setAcutinType(String acutinType) {
this.acutinType = acutinType;
}
public String getCustomer() {
return customer;
}
public void setCustomer(String customer) {
this.customer = customer;
}
}
主程序(MainApp)
package observer;
/**
* @author yingmu
* @version 2011-3-16 下午05:29:40
*/
public class MainApp {
public static void main(String[] args) {
Shop shop = new Shop();
// 添加摄像头1号
Camera camera = new Camera(1);
shop.addObserver(camera);
// 添加门卫一号
Guard guard1 = new Guard("门卫一号");
shop.addObserver(guard1);
// 来访登记、出门登记
shop.comeIn("BlogJava");
shop.comeIn("JavaEye");
shop.getOut("BlogJava");
// 移除门卫一号,上厕所去了
shop.deleteObserver(guard1);
System.out.println(guard1.toString() + "上厕所去了");
// 进入无人观察状态,随进随出
shop.comeIn("优快云");
shop.getOut("JavaEye");
shop.comeIn("樱木");
// 添加门卫二号
Guard guard2 = new Guard("门卫二号");
shop.addObserver(guard2);
// 来访登记,出门登记
shop.comeIn("MS");
shop.getOut("优快云");
}
}
运行结果:
保安门卫一号汇报:BlogJava进入商店
摄像头1号,监控到1个人进入商店,当前店内有1个人
保安门卫一号汇报:JavaEye进入商店
摄像头1号,监控到1个人进入商店,当前店内有2个人
保安门卫一号汇报:BlogJava离开商店
摄像头1号,监控到个人离开商店,当前店内有1个人
门卫一号上厕所去了
摄像头1号,监控到1个人进入商店,当前店内有2个人
摄像头1号,监控到个人离开商店,当前店内有1个人
摄像头1号,监控到1个人进入商店,当前店内有2个人
保安门卫二号汇报:MS进入商店
摄像头1号,监控到1个人进入商店,当前店内有3个人
保安门卫二号汇报:优快云离开商店
摄像头1号,监控到个人离开商店,当前店内有2个人