模式定义
观察者模式定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象。这个主题对象在状态上发生变化时,会通知所有观察者对象,使它们能够自动更新自己。
模式的组成结构
主要角色如下:
- 抽象主题角色:把所有对观察者对象的引用保存在一个集合中,每个抽象主题角色都可以有任意数量的观察者。抽象主题提供一个接口,可以增加和删除观察者角色。一般用一个抽象类和接口来实现。
- 抽象观察者角色:为所有具体的观察者定义一个接口,在得到主题的通知时更新自己。
- 具体主题角色:在具体主题内部状态改变时,给所有登记过的观察者发出通知。具体主题角色通常用一个子类实现。
- 具体观察者角色:该角色实现抽象观察者角色所要求的更新接口,以便使本身的状态与主题的状态相协调。通常用一个子类实现。如果需要,具体观察者角色可以保存一个指向具体主题角色的引用。
示例
以大家找工作为例,都是先联系猎头(相当于在他那里报到),当猎头手头上有工作机会的时候,会逐一通知每个求职者,这就是典型的观察者模式的应用场景了。
1、抽象主题
Subject:
/**
* ${DESCRIPTION}
*
* @author Ricky Fung
* @create 2017-03-26 13:58
*/
public interface Subject {
// 注册方法,用于向观察者集合中增加一个观察者
void attach(Observer observer);
// 注销方法,用于在观察者集合中删除一个观察者
void detach(Observer observer);
void notifyObservers();
}
/**
* ${DESCRIPTION}
*
* @author Ricky Fung
* @create 2017-03-26 13:58
*/
public interface Observer {
void update(Subject subject);
}
职位信息:
/**
* 职位信息
*
* @author Ricky Fung
* @create 2017-03-26 14:12
*/
public class Job {
private String title;
private String location;
private double salary;
public Job(String title, String location, double salary) {
this.title = title;
this.location = location;
this.salary = salary;
}
public String getTitle() {
return title;
}
public String getLocation() {
return location;
}
public double getSalary() {
return salary;
}
@Override
public String toString() {
return "Job{" +
"title='" + title + '\'' +
", location='" + location + '\'' +
", salary=" + salary +
'}';
}
}
猎头,代码如下:
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
/**
* 猎头
*
* @author Ricky Fung
* @create 2017-03-26 13:53
*/
public class Headhunter implements Subject {
private List<Observer> observers = new ArrayList<>();
private String name;
private List<Job> jobs;
public Headhunter(String name) {
this.name = name;
}
public String getName() {
return name;
}
/**更新职位列表**/
public void updateJobs(List<Job> jobs) {
this.jobs = jobs;
notifyObservers();
}
public List<Job> getJobs() {
return Collections.unmodifiableList(this.jobs);
}
@Override
public void attach(Observer observer) {
observers.add(observer);
}
@Override
public void detach(Observer observer) {
observers.remove(observer);
}
@Override
public void notifyObservers() {
for (Observer observer : observers){
observer.update(this);
}
}
}
求职者:
/**
* 求职者
*
* @author Ricky Fung
* @create 2017-03-26 13:52
*/
public class JobSeeker implements Observer {
private String name;
public JobSeeker(String name) {
this.name = name;
}
@Override
public void update(Subject subject) {
Headhunter headhunter = (Headhunter) subject;
System.out.println(name+" received jobs:"+headhunter.getJobs()+" from headhunter:"+headhunter.getName());
}
}
客户端测试:
import java.util.ArrayList;
import java.util.List;
/**
* ${DESCRIPTION}
*
* @author Ricky Fung
* @create 2017-03-26 14:20
*/
public class JobDemo {
public static void main(String[] args) {
Headhunter headhunter = new Headhunter("mike");
headhunter.attach(new JobSeeker("coco"));
headhunter.attach(new JobSeeker("emily"));
headhunter.attach(new JobSeeker("jane"));
List<Job> jobs = new ArrayList<>();
jobs.add(new Job("Java高级工程师", "北京", 18000d));
jobs.add(new Job("Golang高级工程师", "杭州", 15000d));
jobs.add(new Job("公司前台", "北京", 5000d));
headhunter.updateJobs(jobs);
}
}
源码
https://github.com/TiFG/design-patterns/tree/master/observer