一、概述
定义对象之间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新。
二、适用性
1.当一个抽象模型有两个方面,其中一个方面依赖于另一方面的时候。将这二者封装在独立的对象中以使它们可以各自独立地改变和复用。
2.当对一个对象的改变需要同时改变其它对象,而且不知道具体有多少对象需要改变的时候。
3.当一个对象必须通知其它对象,而它又不能假定其它对象是谁的时候。
三、参与者
1.Subject(目标):目标知道它的观察者。可以有任意多个观察者观察同一个目标。提供注册和删除观察者对象的接口。
2.Observer(观察者):为那些在目标发生改变时需要获得通知的对象定义一个更新接口。
3.ConcreteSubject(具体目标):将有关状态存入各ConcreteObserver对象。当它的状态发生改变时,向它的各个观察者发出通知。
4.ConcreteObserver(具体观察者):维护一个指向ConcreteSubject对象的引用。存储有关状态,这些状态应与目标的状态保持一致。实现Observer的更新接口以使自身状态与目标的状态保持一致。
定义对象之间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新。
二、适用性
1.当一个抽象模型有两个方面,其中一个方面依赖于另一方面的时候。将这二者封装在独立的对象中以使它们可以各自独立地改变和复用。
2.当对一个对象的改变需要同时改变其它对象,而且不知道具体有多少对象需要改变的时候。
3.当一个对象必须通知其它对象,而它又不能假定其它对象是谁的时候。
三、参与者
1.Subject(目标):目标知道它的观察者。可以有任意多个观察者观察同一个目标。提供注册和删除观察者对象的接口。
2.Observer(观察者):为那些在目标发生改变时需要获得通知的对象定义一个更新接口。
3.ConcreteSubject(具体目标):将有关状态存入各ConcreteObserver对象。当它的状态发生改变时,向它的各个观察者发出通知。
4.ConcreteObserver(具体观察者):维护一个指向ConcreteSubject对象的引用。存储有关状态,这些状态应与目标的状态保持一致。实现Observer的更新接口以使自身状态与目标的状态保持一致。
四、类图
五、示例
Subject
package cn.lynn.observer;
import java.util.ArrayList;
import java.util.List;
public abstract class Citizen {
protected List<Policeman> polices;
private String action = "normal";
public String getAction() {
return action;
}
public void setAction(String action) {
this.action = action;
}
public void setPolices() {
polices = new ArrayList<Policeman>();
}
public void register(Policeman police) {
polices.add(police);
}
public void unregister(Policeman police) {
polices.remove(police);
}
public abstract void notify(String action);
}
Observer
package cn.lynn.observer;
public interface Policeman {
public void setOut(Citizen citizen);
}
ConcreteSubject
package cn.lynn.observer;
public class DongHuCitizen extends Citizen {
public DongHuCitizen(Policeman police) {
setPolices();
register(police);
}
@Override
public void notify(String action) {
setAction(action);
for (int i = 0; i < polices.size(); i++) {
Policeman police = polices.get(i);
police.setOut(this);
}
}
}
package cn.lynn.observer;
public class NanHuCitizen extends Citizen {
public NanHuCitizen(Policeman police) {
setPolices();
register(police);
}
@Override
public void notify(String action) {
setAction(action);
for (int i = 0; i < polices.size(); i++) {
Policeman police = polices.get(i);
police.setOut(this);
}
}
}
ConcreteObserver
package cn.lynn.observer;
public class DongHuPoliceman implements Policeman {
@Override
public void setOut(Citizen citizen) {
String action = citizen.getAction();
if(action.equals("normal")) {
System.out.println("行为一切正常");
} else if(action.equals("unnormal")) {
System.out.println("有偷窃行为,东湖警察出动!");
}
}
}
package cn.lynn.observer;
public class NanHuPoliceman implements Policeman {
@Override
public void setOut(Citizen citizen) {
String action = citizen.getAction();
if(action.equals("normal")) {
System.out.println("行为一切正常");
} else if(action.equals("unnormal")) {
System.out.println("有抢劫行为,南湖警察出动!");
}
}
}
Client
package cn.lynn.observer;
public class Client {
public static void main(String[] args) {
Policeman dhPolice = new DongHuPoliceman();
Policeman nhPolice = new NanHuPoliceman();
Citizen citizen = new DongHuCitizen(dhPolice);
citizen.notify("normal");
citizen.notify("unnormal");
citizen = new NanHuCitizen(nhPolice);
citizen.notify("normal");
citizen.notify("unnormal");
}
}
Result
行为一切正常
有偷窃行为,东湖警察出动!
行为一切正常
有抢劫行为,南湖警察出动!