观察者模式定义了对象之间的一对多依赖关系,这样一来,当一个对象改变状态时,它的所有依赖者都会收到通知并且自动更新。
观察者依赖于此主题,只要主题状态一有变化,观察者就会被通知。其通知方法可以是可观察者推送数据到观察者,也可以是观察者主动从可观察者中获得数据。
优点:让可观察者和观察者之间实现了松耦合。
缺点:如果一个被观察者对象有很多的直接和间接的观察者的话,将所有的观察者都通知到会花费很多时间。
实例:应聘者和应聘公司之间的关系。应聘者到该公司面试,则注册为该公司的面试人员之一,公司将面试结果下发到每一个应聘者,使他们得知自己的面试结果,结果下发之后,就可以撤消已经得知结果的应聘者。
可观察者接口包含三个方法,注册观察者,撤消观察者,通知事件。
import observer.Observer;
public interface Subject {
public void registerObserver(Observer observer);
public void removeObserver(Observer observer);
public void notifyObserver( );
}
观察者包含两个方法,一是获取可观察者所更新的数据,二是获得数据后所执行的方法
public interface Observer {
public void update(String result);
public void display();
}
应聘公司类实现了Subject接口,其中setData方法用于设置每个面试结果。其中,面试结果分为三种,一是面试通知,二是面试失败,三是结果待定。
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import observable.Subject;
import observer.Observer;
public class Company implements Subject {
private List<Observer> observers = new ArrayList<Observer>();
private Map<String,String> data = new HashMap<String, String>();
public void registerObserver(Observer observer) {
// TODO Auto-generated method stub
observers.add(observer);
}
public void removeObserver(Observer observer) {
// TODO Auto-generated method stub
if (observers.contains(observer))
observers.remove(observer);
}
public void notifyObserver() {
// TODO Auto-generated method stub
for(Observer o : observers){
String result;
result = data.get(((Applicant)o).getName());
if (result == null)
o.update("等待通知");
else
o.update(result);
}
}
public void setData(String name, String result) {
data.put(name, result);
}
}
应聘者如下:
import observable.Subject;
import observer.Observer;
public class Applicant implements Observer {
private String name;
private String result;
private Subject subject;
public Applicant (String name, Subject subject){
this.name = name;
this.subject = subject;
subject.registerObserver(this);
}
public void update(String result) {
// TODO Auto-generated method stub
this.result = result;
display();
}
public void display() {
// TODO Auto-generated method stub
System.out.println("我是" + name + "," + result);
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
测试代码如下:
import entity.Applicant;
import entity.Company;
public class Test {
public static void main(String[] args){
Company company = new Company();
Applicant a1 = new Applicant("小明", company);
Applicant a2 = new Applicant("小红", company);
Applicant a3 = new Applicant("小黑", company);
company.setData(a1.getName(), "面试成功");
company.setData(a2.getName(), "面试失败");
company.notifyObserver();
company.setData(a3.getName(), "面试成功");
company.removeObserver(a1);
company.removeObserver(a2);
System.out.println("几天后...");
company.notifyObserver();
}
}
测试结果如下: