简介 :
- 观察者模式 用于监听一些对象的状态,如果被监听的对象的数据被改变了,那么他的观察者就会知道,并且根据被修改的数据进行一些操作。
问题的引出 :
在这里拿老师与学生来举一个简单的例子
教室里的学生正在听课,教室里面的老师正在上课,窗外的的班主任正在看着教室里面的学生,这个时候教室里面学生属于被观察的对象,而正在上课的老师和班主任则属于观察者,这个时候教室的里面属于听课状态的学生的状态发生改变的话,观察者也就是老师和版主就会知道,并且做出一些措施,大致流程可以用下面这张图表示
具体代码:
首先要有一个容器能够装载观察者和通知观察者
import java.util.ArrayList;
import java.util.List;
import OBserver.Observer;
public abstract class Container {
private List<Observed> list = new ArrayList<Observed>();
//添加观察者
public void addObserved(Observed observed) {
System.out.println("观察者正在观察--->"+observed);
list.add(observed);
}
//通知每个观察者
public void notifydata(StudentState state) {
for (Observed observed : list) {
observed.dosth(state);
}
}
//移除观察者
public void detach(Observer observer){
list.remove(observer);
}
}
然后我们需要一个观察的抽象类与具体实现类
public interface Observed {
public void dosth(StudentState state);
}
public class ObservedTeacher implements Observed{
@Override
public void dosth(StudentState state) {
//根据学生的状态 观察者(老师) 做出一些事情
System.out.println("观察者收到状态开始根据状态做出一些事情--->" +state );
}
}
然后我们好需要一个学生类 这个学生类需要基础container容器,这样当学生类发送变化时能够通知观察者进行更新
public class Student extends Container {
private StudentState state = StudentState.serious;
public void changeState(StudentState state) {
this.state = state;
System.out.println("当前状态--->"+this.state);
this.notifydata(state);
}
}
然后定义一个enum来表达学生类的现在的类型
public enum StudentState {
serious,diver;
}
最后需要一个Main来对观察进行注册 和 学生类的实例化
public class Main {
public static void main(String[] args) {
Student student = new Student();
Observed teacher = new ObservedTeacher();
student.addObserved(teacher);
student.changeState(StudentState.diver);
}
}
最后我们看一下运行结果
观察者正在观察--->ObServerPattern.ObservedTeacher@2a139a55
当前状态--->diver
观察者收到状态开始根据状态做出一些事情--->diver
最后让我们来看一下 我写的这个观察者模式的流程图,到底是怎样运行的
最后需要注意下
- JAVA 中已经有了对观察者模式的支持类。
- 避免循环引用。
- 如果顺序执行,某一观察者错误会导致系统卡壳,一般采用异步方式。