观察者模式详解

观察者模式–快速理解观察者模式

原理解释
实际项目使用场景

原理解释

例子: 当我们在电脑键盘上打字时,敲下”A”,屏幕上会立刻出现一个 “A”。(当然实际上还会有很多处理流程,此处我们简化忽略)

这就可以理解成一个观察者模式,其中:屏幕是一个观察者键盘被观察者数据线则是他们之间的关联(订阅),屏幕时刻在观察着键盘,键盘敲了什么,屏幕就立刻显示什么。

订阅 是观察者和被观察者联系的桥梁,上面的例子中–屏幕到键盘这里做了一个订阅动作(数据线),告诉键盘,如果有任何输入,立马通过数据线告知我。

下面我们通过Java代码实现上面的例子并进行分析:

import java.util.LinkedList;
import java.util.List;

/**
 * 观察者接口
 * 
 * @author stormbaron
 */
interface Oberver {
    // 观察到情况后的动作(回调方法)
    public void work();
}

/**
 * 被观察者接口
 * 
 * @author stormbaron
 */
interface Oberved {
    // 订阅
    public void subscribe(Oberver oberver);

    // 通知所有订阅的观察者
    public void notifyOberver();
}

/**
 * 键盘类(被观察者)
 * 
 * @author stormbaron
 *
 */
class KeyBoard implements Oberved {
    // 观察者集合
    List<Oberver> Obervers = new LinkedList<Oberver>();

    // 订阅
    public void subscribe(Oberver oberver) {
        Obervers.add(oberver);
    }

    // 通知观察者
    public void notifyOberver() {
        if (Obervers != null) {
            for (Oberver mOberver : Obervers) {
                mOberver.work();
            }
        }
    }
}

/**
 * 屏幕类(观察者)
 * 
 * @author stormbaron
 *
 */
class Screen implements Oberver {

    public void work() {
        System.out.println(" I am " + this.toString() + ",I get a Message that KeyBoard imput ");
    }
}

public class ObserverTest {
    public static void main(String[] args) {
        Oberved myKeyBoad = new KeyBoard();
        Oberver myScreen1 = new Screen();
        Oberver myScreen2 = new Screen();
        Oberver myScreen3 = new Screen();
        // 订阅
        myKeyBoad.subscribe(myScreen1);
        myKeyBoad.subscribe(myScreen2);
        myKeyBoad.subscribe(myScreen3);
        // 通知
        myKeyBoad.notifyOberver();
    }

}

上面的代码实现了多个屏幕观察一个键盘,并在键盘发出一个通知后所有订阅的屏幕同时反应。

实际项目使用场景

实际需求
一个Android界面同时显示3个图表,图表数据来自网络,每隔30秒更新一次数据。
思路
View层: 3个Fragment
Control层:Activity
Model层:一个DataModel + HttpUtil 在DataModel提供3个公开的返回特定格式数据方法

此处进行简单MVC模式的分层操作,

此时,我们实际上有许多种方法可以达成目标,例如
(1)在DataModel中利用定时任务,每30秒进行一次网络数据请求,然后更新保存在DataModel中的封装数据(提供给View层)

在Fragment中利用定时任务,定时刷新图表。
(2)利用观察者模式,在DataModel中利用定时任务,每30秒进行一次网络数据请求,然后更新保存在DataModel中的封装数据(提供给View层),同时向所有有订阅关系的Fragment发送通知,使所有Fragment及时刷新图表。

事实上上面两种方式,主要是在View层的数据刷新上有所区别,一种是自己主动不断定时去判断和刷新,另外一种则是被动通知刷新。
从实现角度讲,第一种更简单容易想到和实现,View层和Model层也不需要有任何耦合,但是需要额外运行多个子线程,增加了开销,同时也造成页面数据刷新的不及时。
而第二种方法,利用观察者模式,Fragment实现观察者接口,DataModel实现被观察者接口,将3个Fragment全部订阅到DataModel中,每次DataModel完成数据更新后调用notifyOberver(),通知所有观察者(Fragment)进行数据更新。降低了内存开销,并且及时地进行数据刷新。

评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值