首页 > 代码库 > Java设计模式之观察者模式(Observer Pattern)

Java设计模式之观察者模式(Observer Pattern)

Observer Pattern 是一种常用的设计模式,它是一种事件监听模型。该模式有两个角色,一个是Subject, 另一个是Observer。Subject 保存有多个Observer的引用,一旦特定的事件发生,Subject会通知它所有的Observer,Observer得到该通知后执行相关程序逻辑。其中,Observer只有先向Subject注册后才能被Subject知晓。这就像订报纸,只有我们向出版社提出订报的申请,出版社才会把我们列入订阅者名单,然后每当新报纸印好时,出版社会通知订阅者取报纸。这里订阅的用户就是 Observer, 出版社即 Subject。


Subject , Observer的类图如下:



下面通过一个实例来体会一下观察者模式。

公司需要招聘人才时,往往会去找猎头(headhunter)。猎头知道很多求职者(applicant)的联系方式,一旦有公司招人,猎头就会给这些求职者打电话,以通过他们有工作可以做了。在这里面,猎头就是 Subject,求职者就是 Observer。

我们来实现这样一个功能。设计两个类,HeadHunter 和 Applicant,分别代表猎头和求职者。HeadHunter 类有一个属性 jobName,当jobName有新的值时(相当于公司要招人),HeadHunter 就通知他所知道的所有 Applicant 告诉他们有工作了。类图如下:



Subject 接口定义:

public interface Subject {
	void registerObjserver(Observer ob);
	void removeObserver(Observer ob);
	void notifyObservers();
}

Observer 接口定义:

public interface Observer {
	void update(Subject subject);
}

猎头类定义:

public class HeadHunter implements Subject {
	private List<Observer> obList = new ArrayList<Observer>();

	private boolean isNotify = true;
	private String jobName;

	/**
	 * 注册一个Observer
	 */
	@Override
	public void registerObjserver(Observer ob) {
		obList.add(ob);
	}

	/**
	 * 移除一个Observer
	 */
	@Override
	public void removeObserver(Observer ob) {
		obList.remove(ob);
	}

	/**
	 * 通知所有的Observer
	 */
	@Override
	public void notifyObservers() {
		if (true == isNotify) {
			performNotify();
			isNotify = false;
		}
	}
	
	/**
	 * 添加一个新的工作。添加完成后马上通知所有Observer
	 * @param jobName
	 */
	public void setJobName(String jobName) {
		this.jobName = jobName;

		isNotify = true;
		notifyObservers();
	}
	
	private void performNotify() {
		for (Observer ob : obList) {
			ob.update(this);
		}
	}

	public String getJobName() {
		return jobName;
	}


}

求职者类定义:

public class Applicant implements Observer {
	private String name;
	
	public Applicant(String name) {
		this.name = name;
	}

	@Override
	public void update(Subject subject) {
		HeadHunter h = (HeadHunter)subject;
		out.println(name + "收到通知:" + h.getJobName());
	}


}


这个小程序的功能是,一旦 HeadHunter 的 setJobName() 方法被调用(即有新工作),HeadHunter 马上通知它的 Applicant 告诉他们有工作了。程序测试代码如下:

public static void main(String[] args) {
		HeadHunter hh = new HeadHunter();
		// 注册observer
		hh.registerObjserver(new Applicant("张三"));
		hh.registerObjserver(new Applicant("李四"));
		hh.registerObjserver(new Applicant("王五"));
		
		// 添加一个job
		// 此时所有observer的update()方法都会被调用
		hh.setJobName("Java程序员");
	}



运行结果:



Observer Pattern 在Swing中应用非常广泛,比如调用 JButton 的 addListener() 添加一个事件监听器,此时 JButton 就是 Subject, Listener 就是 Observer。由于观察者模式比较常用,所以需要我们好好体会掌握。