介绍:当我们的程序中,一个对象的行为或状态依赖于另一个对象,我们就可以使用观察者模式。当然,我们也可以另起一个线程来不断监听这个对象的状态,不过这样是会增加程序的开销。JDK中awt和swing的监听事件相关源码中就用的是观察者模式
场景:晚自习的时候,班里的同学有的在写作业,有的在背书,有的在玩手机,聊天。而殊不知老师就在窗边观察着。
其实,观察者模式有两个核心角色:被观察者,观察者。被观察者当其状态改变,则会通知此对象上的观察者。观察者当依赖对象状态改变,被观察者就会通知观察者。
角色 | 作用 |
---|---|
主题接口 | 定义被观察对象的基本操作,需要提供观察者的添加、删除、通知功能 |
具体主题 | 定义被观察对象的基本操作,需要提供观察者的添加、删除、通知功能 |
观察者接口 | 定义观察者的基本方法,需要提供依赖对象状态改变时,本对象的更新功能 |
具体观察者 | 观察者接口的具体实现 |
主题,用于管理监听的观察者,实现数据更新时对他们的通知
public interface Subject {
public void registerObserver(Observer o);
public void removeObserver(Observer o);
public void notifyObserver();
}
具体的被观察者—学生
public class Student implements Subject {
private ArrayList<Observer> observers = new ArrayList<>();
private String state;
@Override
public void registerObserver(Observer o) {
observers.add(o);
}
@Override
public void removeObserver(Observer o) {
int i = observers.indexOf(o);
if (i >= 0) {
observers.remove(i);
}
}
// 通知观察者
@Override
public void notifyObserver() {
for (int i = 0; i < observers.size(); i++) {
observers.get(i).update(state);
}
}
public String getState() {
return state;
}
public void setState(String state) {
this.state = state;
System.out.println("同学正在" + state);
notifyObserver();
}
}
观察者,当主题更新时,调用update来更新数据
public interface Observer {
public void update(String data);
}
具体的观察者—老师
public class Teacher implements Observer {
private Subject subject;
public void observStudent(Subject subject) {
this.subject = subject;
subject.registerObserver(this);
}
@Override
public void update(String data) {
switch (data) {
case "写作业":
System.out.println("老师继续观察");
break;
case "读书":
System.out.println("老师继续观察");
break;
case "聊天":
System.out.println("老师批评");
break;
case "玩手机":
System.out.println("老师没收手机");
break;
}
}
}
监视实例
public static void main(String[] args) {
Student stu = new Student();
Teacher teacher = new Teacher();
teacher.observStudent(stu);
stu.setState("写作业");
stu.setState("聊天");
stu.setState("读书");
stu.setState("玩手机");
}
输出如下
同学正在写作业
老师继续观察
同学正在聊天
老师批评
同学正在读书
老师继续观察
同学正在玩手机
老师没收手机
可以看到,老师根据同学的状态在不断进行操作。
提枪策马乘胜追击04-21 20:01
代码小兵87207-15 12:10
杨晶珍05-11 14:54
杨晶珍05-12 17:30