初探设计模式——观察者模式
一、观察者模式简介
观察者模式,有时又被称为发布(publish )-订阅(Subscribe)模式,是软件设计模式的一种,一个目标物件管理所有依赖于它的观察者物件,并且在它本身状态发生变化时向每一个观察者发出通知。这一般是通过各个观察者所提供的方法来实现。此种设计模式通常被用来实现事件处理系统。
二、观察者模式结构图
观察者模式比较常用的是“注册——通知——取消注册”
(图片来自:百度百科)
抽象观察者(Observer)
抽象观察者,是观察者的抽象类,它定义了一个接口,使得在得到更改通知时更新自己的状态。
具体观察者
具体观察者,是实现了抽象观察者定义的更新接口,使得在得到更改通知时更新自己的状态。
抽象被观察者(Subject)
抽象被观察者,抽象被观察者将所有的观察者保存在一个集合里面,每一个抽象被观察者都可以有任意的观察者,他提供了一组接口,可以增加(注册)和删除(撤销注册)观察者,还可以通知观察者状态更改。
具体被观察者
具体被观察者,实现抽象被观察者的接口,在内部状态发生改变时,给所有注册过的观察者发送通知。
三、观察者模式的简单实现
- ### 抽象观察者(Observer)
public interface Observer {
/*
* 抽象观察者
* */
public void update(String message);
}
- ### 具体观察者
Student是观察者,里面实现了更新方法update
public class Student implements Observer {
/*
* 具体观察者
* */
private String mName;
public Student(String name)
{
mName = name;
}
@Override
public void update(String message) {
System.out.println(mName+"收到了消息:"+message);
}
}
- ### 抽象被观察者
抽象被观察者提供三个接口,分别是attach , detach , notify
public interface Subject {
public void attach(Observer observer); //增加观察者
public void detach(Observer observer); //删除观察者
public void notify(String message); //通知观察者更新消息
}
- ### 具体被观察者
Teacher是被观察者,分别实现attach , detach , notify 这三个接口
public class Teacher implements Subject{
/*
* 具体被观察者
* */
List<Observer> studentList = new ArrayList<>(); //保存观察者的集合
@Override
public void attach(Observer observer) { //实现attach接口,增加观察者
if(observer!=null)
studentList.add(observer);
}
@Override
public void detach(Observer observer) { //实现detach接口,删除观察者
if(observer!=null)
studentList.remove(observer);
}
@Override
public void notify(String message) { //实现notify接口,通过观察者各自实现的方法,在状态改变时通知观察者
for (Observer observer : studentList) {
observer.update(message);
}
}
}
- ### 测试结果
public class Run {
public static void main(String[] args) {
//创建被观察者
Teacher teacher = new Teacher();
//创建三个观察者
Student student = new Student("小芳");
Student student1= new Student("Allen");
Student student2= new Student("Jack");
//分别注册三个观察者
teacher.attach(student);
teacher.attach(student1);
teacher.attach(student2);
//被观察者发出通知,状态发生变化
teacher.notify("明天不上晚自习");
System.out.println("");
//观察者student取消注册
teacher.detach(student);
//被观察者再次发出通知
teacher.notify("今天的早上第一节课上语文");
}
}
测试结果和我们预期一样,当三个观察者在被观察者注册后,被观察者的状态发生变化,通知所有已经注册的观察者,所有的观察者都收到了通知。当有观察者取消注册后,当下次被观察者状态发生变化时,改观察者则不会被通知。