观察者模式的简单使用

前言

我们在Android ListView或者Recyclerview的开发中,常常是数据更新之后要立刻去更新界面,这种Adapter的notifyDateSetChanged就运用了观察者模式;观察者模式是一种使用率非常高的模式,常常用到GUI之类的的系统中,界面跟随数据发生改变,使得UI和具体的页面逻辑分开解耦,换而言之,观察者模式就是一对多的关系,一个对象发生改变,其依赖于它的所有对象都收到通知,更新对象本身。

适用场景

1,事件多级触发场景,一对多关系的一种体现。
2,事件总线场景,这个最多使用的是EventBus。

角色扮演

Subject:被观察者的抽象类,一般提供接口满足添加和删除观察者对象。
ConcreteSubject:具体的被观察者,实现Subject的接口。
Observer:抽象观察者,就是观察者的抽象类,定义更新接口来更新自己的数据。
ConcreteObserver:具体观察者,实现更新自身数据的方法。

观察者模式的简单实现

简单抽象一个demo,我的桌子上有一个电子温度计,其功能就是显示室内温度跟湿度,那么我们抽象的过程就是,当温控原件检测到温度和湿度发生变化时,通知界面刷新,首先我们申明抽象被观察者:

package com.demo.observable;

/**
 * Created by italkbb on 2017/12/25.
 */

/**
 * 被观察者的接口
 */
public interface Subject {

    /**
     * 注册观察者
     */
    void registerObserver(Observer observer);

    /**
     * 移除观察者
     */
    void deleteObservers();

    /**
     * 通知观察者
     */
    void notifyObservers();

}

下面实现这个被观察者:

package com.demo.observable;

import java.util.ArrayList;
import java.util.List;

/**
 * Created by italkbb on 2017/12/25.
 */

public class WeatherSubject implements Subject {
    // 观察者
    private List<Observer> mObservers;
    // 信息
    private float mTemperature;//温度
    private float mHumidity;//湿度

    public WeatherSubject(){
        this.mObservers = new ArrayList<Observer>();
    }

    @Override
    public void registerObserver(Observer observer) {
        this.mObservers.add(observer);
    }

    @Override
    public void deleteObservers() {
        this.mObservers.clear();
    }

    @Override
    public void notifyObservers() {
        for (Observer observer : mObservers) {
            observer.updateInfo();
        }
    }

    public void setWeatherInfo(float temperature, float humidity) {
        this.mTemperature = temperature;
        this.mHumidity = humidity;
        // 信息更新完毕了,通知观察者
        notifyObservers();
    }

    /**
     * 得到测量温度
     * @return
     */
    public float getTemperature() {
        return mTemperature;
    }

    /**
     * 得到测量湿度
     * @return
     */
    public float getHumidity() {
        return mHumidity;
    }
}

上面的类基本满足了设备信息改变通知观察者的功能,下面同样来写观察者:

package com.demo.observable;

/**
 * Created by italkbb on 2017/12/25.
 */

/**
 * 观察者接口
 */
public interface Observer {
    void updateInfo();
}

实现它:

package com.demo.observable;

/**
 * Created by italkbb on 2017/12/25.
 */

public class WeatherInfoDisplay implements Observer {
    private WeatherSubject mWeatherSubject;

    private float mTemperature;//温度
    private float mHumidity;//湿度

    public WeatherInfoDisplay(WeatherSubject weatherSubject){
        this.mWeatherSubject = weatherSubject;
        this.mWeatherSubject.registerObserver(this);
    }

    public void display() {
        // 简单抽象显示为java的打印语句
        System.out.println("温度:" + this.mTemperature + "℃");
        System.out.println("湿度:" + this.mHumidity);
    }

    @Override
    public void updateInfo() {
        this.mTemperature = this.mWeatherSubject.getTemperature();
        this.mHumidity = this.mWeatherSubject.getHumidity();
        display();
    }
}

接下来就简单使用一下:

package com.demo.observable;

import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;

import teltplay.example.com.kotlindemo.R;

public class WeatherActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_weather);
        WeatherSubject mWeatherSubject = new WeatherSubject();
        WeatherInfoDisplay mWeatherInfoDisplay = new WeatherInfoDisplay(mWeatherSubject);

        mWeatherSubject.setWeatherInfo(1.0f,0.36f);
    }
}

就这样一个简单的观察者模式就完成了,当然要实现复杂的逻辑,也就大同小异了。

后记

优点缺点说一下,优点嘛,观察者与被观察者低耦合,也就增加了代码的扩展性;缺点就是如果简单的采取循环通知观察者,可能会由于顺序执行的关系卡住线程,但这个用多线程就会解决,但同时带来的就是效率问题了,太多的观察者,在多线程,资源消耗值得考虑。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值