定義:觀察者設計模式定義了對象間的一種一對多的依賴關係,以便一個對象的狀態發生變化時,全部依賴於它的對象都獲得通知並自動刷新. java
例子:獵頭和求職者模擬觀察者模式 spring
求職者如今獵頭者註冊,當有新的工做機會時獵頭就會通知求職者 設計模式
類圖 this
//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容器事件中的使用: spa
例子:一個模擬的郵件發送器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:模擬發送郵件... code
MailSendListener:向test mail.發送完一封郵件 server
done. xml