观察者模式定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象。这个主题对象在状态发生变化时,会通知所有观察者对象,是它们能够自动更新自己。(引自《大话设计模式》)
观察者模式,又称为发布订阅模式(Publish/Subscribe),顾名思义,发布者发布信息,订阅者接收信息,订阅了就能收到信息,没订阅就不能收到信息。
相关说明:
Subject类
/**
* 抽象主题类(或称为抽象通知类)
*/
public interface Subject {
/**
* 注册观察者
* @param observer
*/
public void registerObserver(Observer observer);
/**
* 删除观察者
* @param observer
*/
public void removeObserver(Observer observer);
/**
* 通知所有注册的观察者
*/
public void notifyObserver();
}
Observer类
/**
* 抽象观察者类
* 当主题类调用notifyObserver()方法时,update()方法会被回调
*/
public interface Observer {
/**
* 更新方法
*/
public void update();
}
ConcreteSubject具体实现类
/**
* 具体主题类(或称为具体通知类)
*/
public class ConcreteSubject implements Subject {
//存储观察者:注意此处List的参数为抽象类Observer,设计原则:面向接口编程,而不是面向实现编程
private List observers = new ArrayList();
//主题类的状态
private String subjectState;
@Override
public void registerObserver(Observer observer) {
observers.add(observer);
}
@Override
public void removeObserver(Observer observer) {
if(!observers.isEmpty() && observers.contains(observer)) {
observers.remove(observer);
}
}
@Override
public void notifyObserver() {
for (Observer observer : observers) {
observer.update();
}
}
public String getSubjectState() {
return subjectState;
}
public void setSubjectState(String subjectState) {
this.subjectState = subjectState;
}
}
ConcreteObserver具体实现类
public class ConcreteObserver implements Observer {
private String name;
private String ObserverMessage;
private ConcreteSubject subject;
public ConcreteObserver(String name, ConcreteSubject subject) {
this.name = name;
this.subject = subject;
}
@Override
public void update() {
this.ObserverMessage = subject.getSubjectState();
System.out.println(this.name+"更新状态为:"+this.ObserverMessage);
}
public ConcreteSubject getSubject() {
return subject;
}
public void setSubject(ConcreteSubject subject) {
this.subject = subject;
}
}
测试类
public class ObserverTest {
public static void main(String[] args) {
ConcreteSubject subject = new ConcreteSubject();
ConcreteObserver observerA = new ConcreteObserver("A",subject);
ConcreteObserver observerB = new ConcreteObserver("B",subject);
ConcreteObserver observerC = new ConcreteObserver("C",subject);
subject.registerObserver(observerA);
subject.registerObserver(observerB);
subject.registerObserver(observerC);
subject.setSubjectState("X");
subject.notifyObserver();
System.out.println("--------------华丽丽的分割线----------------");
//移除B
subject.removeObserver(observerB);
subject.setSubjectState("Y");
subject.notifyObserver();
}
}
测试结果:
一个学校,有一些事情,需要通知该学校所有的学生。
这里的学校就相当于Subject通知者,学生就相当于Observer观察者。
Subject类,这个类不变,此处采用接口。
/**
* 抽象主题类(或称为抽象通知类)
*/
public interface Subject {
/**
* 注册观察者
* @param observer
*/
public void registerObserver(Observer observer);
/**
* 删除观察者
* @param observer
*/
public void removeObserver(Observer observer);
/**
* 通知所有注册的观察者
*/
public void notifyObserver();
}
Observer类,这个类也不变,主要方法就是更新,当学校有事通知(即subject状态改变)时,调用此方法。
/**
* 抽象观察者类
*/
public interface Observer {
/**
* 更新方法
*/
public void update(String message);
}
School类,具体主题实现类,此处为校方,继承Subject类,实现Subject中的方法。声明了List集合,对象为观察者,当自身状态(schoolMessage)发生改变时,遍历list通知所有注册的观察者(学生)。
/**
* 具体主题类(或称为具体通知类)
*/
public class School implements Subject {
//存储观察者
private List observers;
//主题类的状态
private String schoolMessage;
public School() {
observers = new ArrayList();
}
@Override
public void registerObserver(Observer observer) {
observers.add(observer);
}
@Override
public void removeObserver(Observer observer) {
if(!observers.isEmpty() && observers.contains(observer)) {
observers.remove(observer);
}
}
@Override
public void notifyObserver() {
for (Observer observer : observers) {
observer.update(this.schoolMessage);
}
}
public void setMessage(String s) {
this.schoolMessage = s;
System.out.println("学校的状态更新为:"+this.schoolMessage);
notifyObserver();
}
}
Student类,具体观察者实现类。
/**
* 具体观察者类
*/
public class Student implements Observer {
private String name;
private String studentMessage;
public Student(String name) {
this.name = name;
}
@Override
public void update(String message) {
this.studentMessage = message;
System.out.println(this.name+"收到一条新的消息:"+this.studentMessage);
}
}
测试类
public class ObserverTest {
public static void main(String[] args) {
School school = new School();
Student xiaoming = new Student("小明");
Student xiaoqing = new Student("小青");
Student xiaoyun = new Student("小云");
school.registerObserver(xiaoming);
school.registerObserver(xiaoqing);
school.registerObserver(xiaoyun);
school.setMessage("周一升旗仪式要求穿校服。");
System.out.println("--------------华丽丽的分割线----------------");
//小云退学了
school.removeObserver(xiaoyun);
school.setMessage("周五晚上要召开家长会。");
}
}
结果:
好了,就酱紫。用起来很方便,理解起来也比较简单。
当一个对象改变需要同时改变其他对象,并且它不知道有多少对象待改变的时候,可以考虑使用观察者模式。
说在后面:
本文主要是小猫看《大话设计模式》的笔记式的记录,方便以后查阅。
当然了,我也阅读了许多其它博友相关的博文,再加之自己的理解整理出本文,仅供参考。