观察者模式(Observer)别称
1、发布-订阅者模式
2、模型-View 模式
3、源-收听者模式
观察者模式简介
类型:属于行为型设计模式
特点:表示一个对象和多个对象的依赖关系,被观察者对象为一个,观察者对象为多个
场景:被观察者对象的状态(实例变量)发生变化,可以主动告知所有注册的观察者对象
代码举例
一个老师, 多个学生, 当老师的某个状态发生变化,可以通知所有的学生,比如老师布置了最新的作业,可以通知所有学生:作业已经变更!
此时的老师为被观察者对象,所有学生为观察者对象
1、定义一个被观察者接口
说明:该接口规定了作为被观察者对象应该具备的能力(功能),3个方法(注册、反注册、通知)
public interface HomeworkPlan {
public void join(CareHomework careMan); //注册观察者对象
public void quit(CareHomework careMan); //反注册观察者对象
public void notifyEveryone(); //通知每一位观察者对象
}
2、定义一个观察者接口
说明:该接口表示作为观察者对象应该具备的能力有哪些。学生关心作业、家长也可以关心作业,无论是谁,只要具备观察能力的人,都可以作为观察者对象
public interface CareHomework {
public void update(String content); //更新数据
}
3、定义一个具体的被观察者类,它产生的对象表示被观察者对象
Teacher类实现了HomeworkPlan接口,说明Teacher产生的对象具备被观察者对象的能力
public class Teacher implements HomeworkPlan{
private String homeWork;
public void changeHomeWork(String homeWork){
this.homeWork = homeWork;
notifyEveryone();
}
private List<CareHomework> childrenList= new ArrayList<CareHomework>(); //用于保存注册的观察者对象的容器对象
@Override
public void join(Child child) {
childrenList.add(child); //注册观察者,List中添加一个元素,表示注册一个观察者对象
}
@Override
public void quit(Child child) {
childrenList.remove(child); //反注册观察者,删除List中一个元素,表示反注册一个观察者对象
}
@Override
public void notifyEveryone() {
for(Child child : childrenList) {
child.update(homeWork); //遍历List持有的每个观察者对象(Student),调用每个观察者的update方法,表示通知所有观察者对象
}
}
}
4、定义一个具体的观察者类,它产生的对象表示学生
Student类实现了CareHomework接口,说明Student产生的对象具备观察者对象的能力
public class Student implements CareHomework{
private String name;
private String homeWork;
public Student(String name) {
this.name = name;
}
public String getName(){
return name;
}
public String getHomeWork(){
return homeWork;
}
@Override
public void update(String content) {
this.homeWork = content;
}
}
5、定义一个代码入口类
public class Drive {
public static void main(String args[]) {
Teacher teacher = new Teacher(); //被观察者 老师
Student xiaoHua = new Student("小花"); //观察者1 学生
Student xiaoMing = new Student("小明"); //观察者2 学生
Student xiaoJing = new Student("小静"); //观察者3 学生
teacher.join(xiaoHua); //注册观察者1
teacher.join(xiaoMing); //注册观察者2
teacher.join(xiaoJing); //注册观察者3
teacher.changeHomeWork("把作文抄一遍"); //老师发布通知
printHomeWork(xiaoHua); //打印同学收到的通知
printHomeWork(xiaoMing); //打印同学收到的通知
printHomeWork(xiaoJing); //打印同学收到的通知
}
public static void printHomeWork(Student stu){
System.out.println("姓名:" + stu.getName() + "^^^^" + "收到的作业:" + stu.getHomeWork());
}
}
代码关键点
1、定义一个被观察者接口或者抽象类(可省略),该接口或抽象类最少需要规范被观察者对象应该具备的3个基本能力:注册观察者、反注册观察者、通知观察者
2、定义具体的被观察者类
3、具体的被观察者对象需持有一个容器对象,用于持有每一个注册的观察者对象,容器对象的元素类型必须为观察者接口或者观察者抽象类
4、定义观察者接口或者观察者抽象类(可省略)
5、定义具体的观察者类
6、注册观察者对象到被观察者对象中
7、被观察者对象业务逻辑改变后,通知所有观察者对象