观察者模式

  • 观察者模式是什么?

  • 观察者模式的适用场景

  • 观察者模式的使用方法

1. 举个栗子

    当我们对同一组数据进行统计分析的时候,希望能够提供多种表示形式,例如表格、柱状图或者饼状图等。这些表示都依赖于同一组数据,当我们要对数据做出改变的时候,所有的统计的显示都将需要同时改变,也就是我们所说的,当“一”产生变化的时候,我们希望所有依赖这个“一”的“多”都能够发生同步改变。观察者(Observer)模式就是解决了这个问题。

2. 观察者模式是什么?

  • 定义对象间的一种“一对多”的依赖关系,当一个对象(Observable)的状态发生改变时,所有依赖于它的对象(Observer)都会得到通知并被自动更新。(MVC就是观察者模式的一个实例)

  • 观察者模式中主要有观察者(Observer)和被观察者(Observable)两个对象。

  • 被观察者对象是一个抽象类,所以只能被继承。

  • 观察者对象是一个接口,所以观察者可以有多个,实现了该接口的类都属于观察者。

  • 一个对象既可以是观察者,又可以是被观察者。它可以继承Observable类,同时又可以实现Observer接口。

3. 观察者模式的适用场景

    一个对象的状态更新了,需要其他对象同步更新,这个对象只需要将自己更新了这个消息通知给其他对象,而不需要知道其他对象的数量及其更新细节。

4. 观察者模式的使用方法

  • 实例:被观察者为一个数字,有两个观察者,一个做加法,另一个做乘法,每次将被观察者进行加1的操作,两个观察者发生相应的变化。


  • 被观察者MyObservable,继承Observable。

public class MyObservable extends Observable {

    private String content;

    public String getContent() {
        return content;
    }

    public void setContent(String content) {
        this.content = content;
        setChanged();// 确认数据已经发生变化
        notifyObservers();// 发送信号通知观察者
    }
}
  • 观察者MyObserver,实现Observer接口。

public class MyObserver implements Observer {

    private MyObservable myObservable;

    public MyObservable getMyObservable() {
        return myObservable;
    }

    public void setMyObservable(MyObservable myObservable) {
        this.myObservable = myObservable;
    }

    @Override
    public void update(Observable o, Object arg) {
        this.myObservable = (MyObservable) o;
    }

    public int getObservableValue(){

        if (EmptyUtils.isEmpty(getMyObservable()))
            return 0;

        if (EmptyUtils.isEmpty(getMyObservable().getContent()))
            return 0;

        return Integer.parseInt(getMyObservable().getContent());
    }
}
  • 创建被观察者对象和两个观察者对象,被观察者通过addObserver()方法添加观察者对象observer1和observer2,然后改变被观察者的值,依次加1,观察者可以通过获取被观察者的值而分别发生相应的变化。实现方法如下:

public class ObserverMainActivity extends BaseActivity {

    @BindView(R.id.title_name_tv)
    TextView titleNameTv;// 标题
    @BindView(R.id.observable_tv)
    TextView mObservableTv;// 被观察者
    @BindView(R.id.observer_add_tv)
    TextView mObserverAddTv;// 观察者一,做加法
    @BindView(R.id.observer_multip_tv)
    TextView mObserverMulTv;// 观察者二,做乘法

    private int i = 1;
    private MyObservable myObservable;
    private MyObserver observer1;
    private MyObserver observer2;

    @Override
    protected int getLayoutResId() {
        return R.layout.activity_observer_main;
    }

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        titleNameTv.setText("观察者模式");

        myObservable = new MyObservable();

        observer1 = new MyObserver();
        observer2 = new MyObserver();

        myObservable.addObserver(observer1);
        myObservable.addObserver(observer2);

        myObservable.setContent(i + "");
        notifyView();
    }

    @OnClick(R.id.change_observable_btn)
    void onClick(View view) {
        i++;
        myObservable.setContent(i + "");
        notifyView();
    }

    /**
     * 刷新数据
     */
    private void notifyView() {
        mObservableTv.setText(myObservable.getContent());
        mObserverAddTv.setText((observer1.getObservableValue() + observer1.getObservableValue()) + "");
        mObserverMulTv.setText((observer2.getObservableValue() * observer2.getObservableValue()) + "");
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();

        myObservable.deleteObservers();
    }
}

5. 观察者模式的优缺点

  • 优点

          (1) 观察者模式在被观察者和观察者之间建立一个抽象的耦合。被观察者只知道一个具体的观察者列表,但并不认识任何一个具体的观察者,它只知道它们都有一个共同的接口,而每一个具体的观察者都会实现这样一个抽象接口。

          (2) 观察者模式支持广播通讯。被观察者会向所有的登记过的观察者发出通知。


  • 缺点

    (1) 如果被观察者之间存在循环依赖的关系,那么将会导致系统崩溃;

    (2) 如果对观察者的通知是通过另外的线程进行异步投递的话,那么系统必须保证投递是以自洽的方式进行的;

    (3) 观察者只知道被观察者发生了变化,但是不知道被观察者是怎么发生变化的。









评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值