在学校里,每个班级都有一个班主任和若干班委,当班主任有新的任务布置时,班委就会接到任务通知。当有新的班委任命时,新的班委也会接到任务通知;当有班委申请退出时,这个原班委就接不到任务通知 ----这是我对于观察者模式的通俗解释。
将这情况普遍化:班主任视为主题,班委视为观察者,当主题的内容发生了改变,观察者可以接收到内容的变化。
观察者模式的定义了对象之间的一对多依赖,这样一来,当一个对象改变状态时,他的所有依赖者都会收到通知并自动更新
用UML类图表示:
主题接口
/**
*
* @author Lvxus
* 主题接口,声明了注册、移除、通知观察者的方法
*
*/
public interface Subject {
public void registerObserve(Observe obs);
public void removeObserve(Observe obs);
public void notifyObserve();
}
观察者接口
/**
*
* @author Lvxus
*
* 观察者接口,声明了更新内容方法
*
*/
public interface Observe {
public void update(String task);
}
班主任实现主题接口
/**
*
* @author Lvxus
*
* 主题接口的实现类,实现subject接口
*
*/
public class Teacher implements Subject{
//观察者列表
private List<Observe> observes;
//班主任布置的任务
private String task;
//实例化主题时,产生观察者列表
public Teacher(){
observes = new ArrayList<Observe>();
}
@Override
public void registerObserve(Observe obs) {
// TODO Auto-generated method stub
observes.add(obs);
}
@Override
public void removeObserve(Observe obs) {
// TODO Auto-generated method stub
//当观察者在列表中
if (observes.indexOf(obs) != -1) {
observes.remove(obs);
}
}
@Override
public void notifyObserve() {
// TODO Auto-generated method stub
//遍历观察者列表,通知各位观察者
for (Observe observe : observes) {
observe.update(task);
}
}
public void setTask(String task){
this.task = task;
System.out.println("班主任布置新的任务"+task);
notifyObserve();
}
}
学生实现观察者接口
/**
*
* @author Lvxus
*
* 学生实现观察者接口
*
*/
public class Student implements Observe{
private Subject subject;
private String task;
public Student(Subject subject) {
// TODO Auto-generated constructor stub
this.subject = subject;
subject.registerObserve(this);//当此学生对象实例化,这个学生对象就会被注册成观察者
}
@Override
public void update(String task) {
// TODO Auto-generated method stub
this.task = task;
display();
}
private void display() {
// TODO Auto-generated method stub
System.out.println("班委接到新任务" + task);
}
}
实现类
/*
* 实现类
*/
public class PublishTask {
public static void main(String[] args){
Teacher teacher = new Teacher();//建立一个班主任对象
Student student = new Student(teacher);//建立一个班委对象
teacher.setTask("今天不上课");//老师布置任务
}
}
实现的结果:
班主任布置新的任务今天不上课
班委接到新任务今天不上课
观察者模式的好处是,观察者和主题松耦合,当主题增加内容,并不会对原观察者接收的内容发生影响,如,当老师类添加一个作业(homework)属性,原接收任务(task)属性的班委并不会接收到作业(homework)属性的内容,这时候可以让不同的学生接收不同的内容。
同时,当任务(task)属性的内容发生更新,能接受任务内容的学生所接收到的任务也进行了更新。
java也内置观察者模式,但被观察者,即主题是一个类并非接口,降低了可复用性
以上,是小生对观察者模式的初步理解,若有不对的地方,烦请指正
参考书籍:《Head First 设计模式》