1. Java之观察者模式(Observer Pattern)
(1)概述:
生活中我们在使用新闻app,当我们对某一栏比较感兴趣,我们往往会订阅这栏新闻,比如我对军事栏感兴趣,我就会订阅军事栏的新闻。这样的话,一旦有了军事栏新闻更新,App就会自动弹出通知告知我们。
这就是观察者模式,她定义对象间的一种一对多的依赖关系,当一个对象(被观察者)的状态发生改变时, 所有依赖于它的对象(观察者)都得到通知并被自动更新。
(2)观察者模式的UML类图:
角色介绍:
1)Subject:抽象主题,也就是被观察者(Observable)角色,抽象主题角色把所有观察者对象的引用保存在一个集合之中,每个主题都可以有任意数量的观察者,抽象主题提供一个接口,可以增加和删除观察者对象。
2)ConcreteSubject:具体主题,该角色将有关状态存入具体观察者对象,在具体主题的内部状态发生变化时候,给所有注册过的观察者发出通知,具体主题角色又叫具体被观察者(Concrete Observable)角色。
3)Observer:抽象观察者,该角色是观察者的抽象类,它定义了一个更新的接口,使得在得到主题的更改通知时候更新自己。
4)ConcreteObserver:具体的观察者,该角色实现抽象观察者角色定义的更新接口,以便在主题的状态发生变化的时候更新自身的状态。
2. 观察者模式代码实现:
(1)下面是一个猎头的典型例子。这个图中有2个角色-猎头和求职者。求职者先在猎头处注册,当有新的工作机会时猎头就会通知求职者。
观察者模式—猎头和求职者的UML图,如下:
(2)新建Java工程,如下:
Subject(接口):抽象主题,被观察者角色。
1 package com.himi.observable; 2 3 import com.himi.observer.Observer; 4 5 public interface Subject { 6 public void registerObserver(Observer o); 7 8 public void removeObserver(Observer o); 9 10 public void notifyAllObservers(); 11 }
HeadHunter:具体主题,具体被观察者者角色。
1 package com.himi.observable; 2 3 import java.util.ArrayList; 4 5 import com.himi.observer.Observer; 6 7 public class HeadHunter implements Subject { 8 9 //define a list of users, such as Mike, Bill, etc. 10 private ArrayList<Observer> userList; 11 private ArrayList<String> jobs; 12 13 public HeadHunter(){ 14 userList = new ArrayList<Observer>(); 15 jobs = new ArrayList<String>(); 16 } 17 18 @Override 19 public void registerObserver(Observer o) { 20 userList.add(o); 21 } 22 23 @Override 24 public void removeObserver(Observer o) {} 25 26 @Override 27 public void notifyAllObservers() { 28 for(Observer o: userList){ 29 o.update(this); 30 } 31 } 32 33 public void addJob(String job) { 34 this.jobs.add(job); 35 notifyAllObservers(); 36 } 37 38 public ArrayList<String> getJobs() { 39 return jobs; 40 } 41 42 public String toString(){ 43 return jobs.toString(); 44 } 45 46 }
Observer(接口):抽象观察者,观察者的抽象类。
1 package com.himi.observer; 2 3 import com.himi.observable.Subject; 4 5 public interface Observer { 6 public void update(Subject s); 7 }
JobSeeker:具体的观察者。
1 package com.himi.observer; 2 3 import com.himi.observable.Subject; 4 5 public class JobSeeker implements Observer { 6 7 private String name; 8 9 public JobSeeker(String name){ 10 this.name = name; 11 } 12 @Override 13 public void update(Subject s) { 14 System.out.println(this.name + " got notified!"); 15 //print job list 16 System.out.println(s); 17 } 18 19 }
最后我们测试一下观察者模式代码如下:
1 package com.himi.test; 2 3 import com.himi.observable.HeadHunter; 4 import com.himi.observer.JobSeeker; 5 6 public class Test { 7 8 public static void main(String[] args) { 9 HeadHunter hh = new HeadHunter(); 10 hh.registerObserver(new JobSeeker("Mike")); 11 hh.registerObserver(new JobSeeker("Chris")); 12 hh.registerObserver(new JobSeeker("Jeff")); 13 14 //每次添加一个个job,所有找工作人都可以得到通知。 15 hh.addJob("Baidu Job"); 16 hh.addJob("Alibaba Job"); 17 hh.addJob("Tecent Job"); 18 } 19 20 }
运行程序如下: