直接崩溃了,看了好长时间才明白一点其中的意思,先初次记录一下,等有更深层次的理解时再继续编辑。
在《Head.First设计模式》中,对观察者模式的解释非常生动,理解起来也很容易,但是,真正自己写一个实现为什么怎么就这么难呢?哎……好吧,记录一下主要的学习内容。
一、观察者模式引入
首先,说一下这个被称为皇后的观察者模式:观察者模式定义了一系列对象之间的一对多依赖关系;当一个对象改变状态,其他依赖者都会收到通知并自动更新。其中,“一”指的是主题,“多”指的是观察者。观察者可以“注册”后获得“主题”改变时的及时通知。
如果还不是很好理解,我们继续:比如有读者乐乐、皮皮、大皮皮、破皮。出版社发放报纸,四位读者可以订阅。如果乐乐想订阅,那么,他会告诉出版商,我要订阅报纸,之后,出版社一有新的报纸出来的时候,就会及时发放到乐乐手中。同理,皮皮想订阅的话,也可以这样。如果订阅一段时间后,乐乐不想订了,可以直接告诉出版商,我不订阅了,这样,之后的信息更新就不会再通知给乐乐。 观察者模式就是这样一个过程,可以灵活的接受对象的“注册”,也可以允许用户对象“注销”。“注册”的用户可以及时得到主题对象的更新内容,而没有订阅的就不能得到。
下面是类图:
二、观察者模式设计举例
实现功能:学校发布信息,学生可以订阅,老师可以订阅,行政人员也可以订阅。
思路:定义主题接口,观察者接口,定义Notice 、学生、老师和行政人员类,定义测试类。其中Notice类实现主题接口,老师、学生和行政人员实现观察者接口。
实现过程:(注释中有解释)
1、定义主题接口
- public interface Subjects{
- //注册订阅用户
- public void registerObservers(Observer o);
- //对用户发送新的通知
- public void notifyObservers();
- //注销用户
- public void removeObservers(Observer o);
- }
2、定义观察者接口
- public interface Observer{
- //notice通过调用此方法实现向订阅者发送信息的功能
- public void givenotice(String s);
- }
3、定义Notice类
- import java.util.ArrayList;
- //实现主题接口
- public class Notice implements Subjects{
- private String ss = new String();
- private ArrayList observers;
- public Notice(){
- observers = new ArrayList();
- }
- //主题接口方法,注销订阅用户
- public void removeObservers(Observer o){
- int i = observers.indexOf(o);
- if (i>=0){
- observers.remove(i);
- }
- }
- //主题接口方法,添加订阅的用户
- public void registerObservers (Observer o){
- observers.add(o);
- }
- //主题接口方法,通过遍历向订阅者发送消息
- public void notifyObservers(){
- for (int i=0; i<observers.size();i++){
- Observer observer = (Observer)observers.get(i);
- observer.givenotice(ss);
- }
- }
- //供测试用
- public void setContent(String ss){
- this.ss = ss;
- this.notifyObservers();
- }
- }
4、定义Student类
- public class Student implements Observer{
- //实现Observer的方法
- public void givenotice(String ss){
- System.out.println("学生:"+ss);
- }
- }
5、再定义一个Teacher类
- public class Teacher implements Observer{
- //实现observers中的givenotice()方法
- public void givenotice(String ss){
- System.out.println("老师:"+ss);
- }
- }
6、用Test类实现测试
- public class Test{
- //这是测试
- public static void main(String args[]){
- Notice n = new Notice();
- Student student = new Student();
- Teacher teacher = new Teacher();
- n.registerObservers(student);
- n.registerObservers(teacher);
- //因为没有可以自动调用Notice中的方法的实现,所以,只好通过这个测试了
- n.setContent("ahaha");
- //注销student用户
- n.removeObservers(student);
n.setContent("ahaha"); - }
- }
7、输出结果
学生:ahaha
老师:ahaha
老师:ahaha(注销student后)