定义:观察者设计模式定义了对象间的一种一对多的依赖关系,以便一个对象的状态发生变化时,所有依赖于它的对象都得到通知并自动刷新.
例子:猎头和求职者模拟观察者模式
求职者现在猎头者注册,当有新的工作机会时猎头就会通知求职者
类图
//Subject:
public interface Subject {
public void registerObserver(Observer o);
public void removeObserver(Observer o);
public void notifyAllObservers();
}
//Observer
public interface Observer {
public void update(Subject s);
}
//HeadHunter
public class HeadHunter implements Subject {
private ArrayList<Observer> userList;
private ArrayList<String> jobs;
public HeadHunter(){
userList = new ArrayList<Observer>();
jobs = new ArrayList<String>();
}
public void registerObserver(Observer o) {
userList.add(o);
}
public void removeObserver(Observer o) {}
public void notifyAllObservers() {
for(Observer o: userList){
o.update(this);
}
}
//通知求职者
public void addJob(String job) {
this.jobs.add(job);
notifyAllObservers();
}
public ArrayList<String> getJobs() {
return jobs;
}
//重写toString方法
public String toString(){
return jobs.toString();
}
}
//JobSeeker
public class JobSeeker implements Observer {
private String name;
public JobSeeker(String name){
this.name = name;
}
public void update(Subject s) {
System.out.println(this.name + " got notified!");
System.out.println(s);
}
}
//Test
public class Test {
public static void main(String[] args) {
HeadHunter hh = new HeadHunter();
hh.registerObserver(new JobSeeker("Mike"));
hh.registerObserver(new JobSeeker("Chris"));
hh.registerObserver(new JobSeeker("Jeff"));
//每次添加一个个job,所有找工作人都可以得到通知。
hh.addJob("百度 Job");
hh.addJob("阿里 Job");
}
}
//执行结果
Mike got notified!
[百度 Job]
Chris got notified!
[百度 Job]
Jeff got notified!
[百度 Job]
Mike got notified!
[百度 Job, 阿里 Job]
Chris got notified!
[百度 Job, 阿里 Job]
Jeff got notified!
[百度 Job, 阿里 Job]
观察者模式在Spring容器事件中的使用:
例子:一个模拟的邮件发送器MailSender,它向目的地发送邮件时,将产生一个MailSendEven的事件,容器中注册了监听该事件的监听器MailSendListener.
//邮件发送器MailSender
public class MailSender implements ApplicationContextAware {
private ApplicationContext ctx ;
public void setApplicationContext(ApplicationContext ctx)
throws BeansException {
this.ctx = ctx;
}
public void sendMail(String to){
System.out.println("MailSender:模拟发送邮件...");
MailSendEvent mse = new MailSendEvent(this.ctx,to);
ctx.publishEvent(mse);
}
}
//MailSendEven事件
public class MailSendEvent extends ApplicationContextEvent {
private String to;
//source 事件源 to 目标
public MailSendEvent(ApplicationContext source, String to) {
super(source);
this.to = to;
}
public String getTo() {
return this.to;
}
}
//监听器MailSendListener
public class MailSendListener implements ApplicationListener<MailSendEvent>{
public void onApplicationEvent(MailSendEvent event) {
MailSendEvent mse = (MailSendEvent) event;
System.out.println("MailSendListener:向" + mse.getTo() + "发送完一封邮件");
}
}
//eventbeans.xml
<?xml version="1.0" encoding="UTF-8" ?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">
<bean class="event.MailSendListener"/>
<bean id="mailSender" class="event.MailSender"/>
</beans>
//Test
public class ApplicationEventTest {
public static void main(String[] args) {
ApplicationContext ctx = new ClassPathXmlApplicationContext("eventbeans.xml");
MailSender mailSender = ctx.getBean(MailSender.class);
mailSender.sendMail("test mail.");
System.out.println("done.");
}
}
MailSender:模拟发送邮件...
MailSendListener:向test mail.发送完一封邮件
done.
原文:http://my.oschina.net/u/2361475/blog/527298