JAVA设计模式 观察者模式

来源:互联网 发布:高中生学编程 编辑:程序博客网 时间:2024/06/08 10:13

定义

定义对象间一种一对多的依赖关系,使得每当一个对象改变状态,则所有依赖于它的对象都会得到通知,并自动更新

观察者模式的使用场景

1 关联行为场景,需要注意的是,关联行为是可拆分的,而不是组合关系

2 时间多级触发场景

3跨系统的消息交换场景,例如,消息队列,事件总线的处理机制

观察者模式的UML图

这里写图片描述

这里写图片描述

下面来看一下一个小例子

老师和同学,同学要订阅老师,然后老师发布作业,同学就自动会收到老师的信息

//观察者public interface Observer {    public void updata(String work);}
//集体观察者public class StudentObserver implements Observer {    private final Subject mSubject;    private String mName;    private String mWork;    public StudentObserver(String name, Subject subject) {        this.mName = name;        this.mSubject = subject;        this.mSubject.registerObserver(this);    }    @Override    public void updata(String work) {        Log.d("mmmobserver", mName + "今天作业是" + work);    }}
//主题(被观察者)public interface Subject {    public void registerObserver(Observer observer);    public void romoveObserver(Observer observer);    public void nofityObserver();}
//具体被观察者public class TeacherSubject implements Subject {    private final ArrayList<Observer> mObservers;    private String mWork;    public TeacherSubject() {        mObservers = new ArrayList<>();    }    @Override    public void registerObserver(Observer observer) {        mObservers.add(observer);    }    @Override    public void romoveObserver(Observer observer) {        if (mObservers.indexOf(observer)>=0){            mObservers.remove(observer);        }    }    @Override    public void nofityObserver() {        for (Observer o:mObservers) {            o.updata(mWork);        }    }    public void setHomework(String work){        this.mWork=work;        this.nofityObserver();        Log.d("mmmsubject","今天作业是"+work);    }}

调用

public class ObserverActivity extends BaseActivity {    @Override    public int setMainView() {        return R.layout.activity_observer;    }    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setToobarTitle("观察者模式");        TeacherSubject teacherSubject = new TeacherSubject();        StudentObserver 张三 = new StudentObserver("张三", teacherSubject);        StudentObserver 李四 = new StudentObserver("李四", teacherSubject);        StudentObserver 王五 = new StudentObserver("王五", teacherSubject);        teacherSubject.setHomework("第五页第一题");        teacherSubject.setHomework("第五页第二题");        teacherSubject.setHomework("第五页第三题");    }}

界面显示

10-18 09:36:47.911 11947-11947/com.example.jh.rxhapp D/mmmobserver: 张三今天作业是第五页第一题
10-18 09:36:47.911 11947-11947/com.example.jh.rxhapp D/mmmobserver: 李四今天作业是第五页第一题
10-18 09:36:47.911 11947-11947/com.example.jh.rxhapp D/mmmobserver: 王五今天作业是第五页第一题
10-18 09:36:47.911 11947-11947/com.example.jh.rxhapp D/mmmsubject: 今天作业是第五页第一题
10-18 09:36:47.911 11947-11947/com.example.jh.rxhapp D/mmmobserver: 张三今天作业是第五页第二题
10-18 09:36:47.913 11947-11947/com.example.jh.rxhapp D/mmmobserver: 李四今天作业是第五页第二题
10-18 09:36:47.913 11947-11947/com.example.jh.rxhapp D/mmmobserver: 王五今天作业是第五页第二题
10-18 09:36:47.913 11947-11947/com.example.jh.rxhapp D/mmmsubject: 今天作业是第五页第二题
10-18 09:36:47.913 11947-11947/com.example.jh.rxhapp D/mmmobserver: 张三今天作业是第五页第三题
10-18 09:36:47.913 11947-11947/com.example.jh.rxhapp D/mmmobserver: 李四今天作业是第五页第三题
10-18 09:36:47.913 11947-11947/com.example.jh.rxhapp D/mmmobserver: 王五今天作业是第五页第三题
10-18 09:36:47.913 11947-11947/com.example.jh.rxhapp D/mmmsubject: 今天作业是第五页第三题

这样就达到目的了

我是做Android 的,如果做Android 的话就会知道有一个第三方EventBus,他就是典型的观察者模式,我在这里简单口述一下他的工作原理

EventBus.getDefault().register(this);这个注册会把 当前类也就是this(c),和 类中OnEvent开头的方法(m),和方法其中的参数(p),存到一个Map中,以p作为 key ,以c和m组成的对象作为 value;把这个map存起来,然后 EventBus.getDefault().post(new UpdateReplyEvent());的时候,以post中的参数从map中取出,c和m,再利用反射直接调用该方法就行,这就是大概原理,详细请看源码

现在说一下观察者模式和回调的区别

先看一个回调的例子,也是学生和老师

public interface CaStudent {    public void onCallBack(String work);}
public class CaTeacher {    private CaStudent mCallback;    //注册事件    public void register(CaStudent callBack) {        this.mCallback = callBack;    }    public void setWork(String work) {        mCallback.onCallBack(work);    }}
public class ObserverActivity extends BaseActivity {    @Override    public int setMainView() {        return R.layout.activity_observer;    }    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setToobarTitle("观察者模式");        CaTeacher caTeacher = new CaTeacher();        caTeacher.register(new CaStudent() {            @Override            public void onCallBack(String work) {                Log.d("mmmcallback", "今天作业是" + work);            }        });     caTeacher.setWork("打游戏");    }}

最后打印

10-19 03:13:51.924 5617-5617/com.example.jh.rxhapp D/mmmcallback: 今天作业是打游戏

这个就是我们经常用的回调,可以看出回调中Cateacher只维护了一个 CaStudent ,而 观察者中维护了一个list的student,所以回调其实是简单的观察者

   private final ArrayList<Observer> mObservers;    public TeacherSubject() {        mObservers = new ArrayList<>();    }

区别是观察者模式里面目标类维护了所有观察者的引用,而回调里面只是维护了一个引用。

原创粉丝点击