观察者模式的一点小理解

关于java 的 观察者 模式 的基本概念和 使用可以看: Java_观察者模式(Observable和Observer)
补充:最近还有 “Rxjava” 这个 比较火的 基于观察者模式的异步架构,但我想先研究好观察者源码再去引入Rxjava 到我的工程中。
本文主要是进行观察者 的一些简单的使用分析,如有错误,还望指教。
一、为什么要使用观察者?
如果只是简单的需要回调与通知,完全可以写一个简单 的回调方式 ,例子如下:
一个要 “被观察”的类,代码如下

public class UpdateSrc {

    Callback callback = null;

    public void changeSrc(String data){ 
        System.out.println("简单 被观察者 获取到新数据->"+data);
        callback.onCallback(data);
    }

    public void setCallBack(Callback callback){
        this.callback = callback;
    }

    public static interface Callback{
        public void onCallback(Object data);
    }

}

一个 “观察数据”的类,如下:

public class UpdateObserver {
    void setDataSrc(UpdateSrc src){
        src.setCallBack(new UpdateSrc.Callback() {

            @Override
            public void onCallback(Object data) {
                System.out.println("简单 观察者 获取到数据->"+data);

            }
        });
    }

}

测试代码如下:

        UpdateSrc src = new UpdateSrc();
        UpdateObserver observer = new UpdateObserver();
        observer.setDataSrc(src);
        src.changeSrc("数据一");
        src.changeSrc("数据二");
        src.changeSrc("数据三");
        src.changeSrc("数据四");

测试结果如下:

简单 被观察者 获取到新数据->数据一
简单 观察者 获取到数据->数据一
简单 被观察者 获取到新数据->数据二
简单 观察者 获取到数据->数据二
简单 被观察者 获取到新数据->数据三
简单 观察者 获取到数据->数据三
简单 被观察者 获取到新数据->数据四
简单 观察者 获取到数据->数据四

看起来简单好用又没啥大毛病,那么为啥java还要给大伙儿提供 Observer 接口 和 Observable 类呢?目前仅仅看代码模式可以看到两大优势,当然欢迎各位小伙伴留言补充,我会再依次看情况整理添加上来
一、一定程度的解耦:
首先回顾我写的“UpdateObserver”类,发现了了么?它很容易就把“UpdateSrc” 类加进来了,一部小心就造成代码耦合了,哪天你要删除 “UpdateSrc” 类,就也得修改“UpdateObserver”类的代码。
如果使用观察模式呢?
可以看如下代码:

被观察者的代码

import java.util.Observable;

public class MyObservable extends Observable {


    public void setData(String data){
        System.out.println("被观察者 获取到新数据->"+data);
        setChanged();
        notifyObservers(data);
    }

}

观察者的代码如下

import java.util.Observable;
import java.util.Observer;

public class MyObserver implements Observer{

    public MyObserver(Observable observable) {
        observable.addObserver(this);
    }

    @Override
    public void update(Observable o, Object arg) {
        System.out.println("观察者 获取到的数据->"+arg);
    }

}

看上述代码,没有耦合引用到“MyObservable”类 的地方

测试代码如下:

        MyObservable observable = new MyObservable();
        MyObserver observer = new MyObserver(observable);
        observable.setData("数据一");
        observable.setData("数据二");
        observable.setData("数据三");

测试结果如下:

被观察者 获取到新数据->数据一
观察者 获取到的数据->数据一
被观察者 获取到新数据->数据二
观察者 获取到的数据->数据二
被观察者 获取到新数据->数据三
观察者 获取到的数据->数据三

解耦总结:实现Observer ,继承 Observable,可以减低耦合,当然,如果硬是把上述的第一种情况也做到低耦合,也不是不可以,将 UpdateSrc.Callback 这个 内部类 改成一个独立类,但是这样一来,不就和sdk提供的Observer 更相似了么?直接使用Observer 不更简单省事儿?
第二、比较容易实现“多对多的callback模式”
1、”多对一”的情况,数个observable有数据的时候,要传递数据到同一个observer
这里写图片描述
2、“一对多”的情况, 一个observable有数据的时候,要传递给数个observer
这里写图片描述
3、“多对多”的情况,数据个obervable有数据的时候,要传递给数个observer
这里写图片描述
现在我们基于第三种场景来改代码

被观察者代码如下

public class MyObservable extends Observable {
    private String mName = null;

    public MyObservable(String name) {
        mName = name;
    }

    @Override
    public String toString() {
        return mName;
    }

    public void setData(String data) {
        System.out.println(mName + " 获取到新数据->" + data);
        setChanged();
        notifyObservers(data);
    }
}

观察者的代码如下:

public class MyObserver implements Observer {
    private String mName = null;

    public MyObserver(String name) {
        mName = name;
    }


    @Override
    public void update(Observable o, Object arg) {
        System.out.println(mName + " 获取到的数据->" + arg + " 数据来源是->" + o);

    }
}

测试代码如下

        MyObserver myObserver1 = new MyObserver("观察者1");
        MyObserver myObserver2 = new MyObserver("观察者2");
        MyObserver myObserver3 = new MyObserver("观察者3");
        MyObservable myObservable1 = new MyObservable("被观察者1");
        MyObservable myObservable2 = new MyObservable("被观察者2");
        MyObservable myObservable3 = new MyObservable("被观察者3");

        myObservable1.addObserver(myObserver1);
        myObservable1.addObserver(myObserver2);
        myObservable1.addObserver(myObserver3);
        myObservable1.setData("数据一");

        myObservable2.addObserver(myObserver1);
        myObservable2.addObserver(myObserver2);
        myObservable2.addObserver(myObserver3);
        myObservable2.setData("数据二");


        myObservable3.addObserver(myObserver1);
        myObservable3.addObserver(myObserver2);
        myObservable3.addObserver(myObserver3);
        myObservable3.setData("数据3");

运行结果如下:

被观察者1 获取到新数据->数据一
观察者3 获取到的数据->数据一 数据来源是->被观察者1
观察者2 获取到的数据->数据一 数据来源是->被观察者1
观察者1 获取到的数据->数据一 数据来源是->被观察者1
被观察者2 获取到新数据->数据二
观察者3 获取到的数据->数据二 数据来源是->被观察者2
观察者2 获取到的数据->数据二 数据来源是->被观察者2
观察者1 获取到的数据->数据二 数据来源是->被观察者2
被观察者3 获取到新数据->数据3
观察者3 获取到的数据->数据3 数据来源是->被观察者3
观察者2 获取到的数据->数据3 数据来源是->被观察者3
观察者1 获取到的数据->数据3 数据来源是->被观察者3

总结:一定程度上来讲,观察者模式的使用就比普通的设置interface callback 类要强大一些,但是,我们通过阅读observabel 类可以知道,观察者是产生了一定的额外代码消耗的,我们更应该依照自己面对的场景选择合适的方法。
补充:欢迎各位小伙伴留言交流,提出更多的场景,我得以补充文章内容,大家相互学习。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值