该连带依赖对象清一色落关照并受自动更新。观察者模式。

动用实例

public class MeUser extends Observable {

    private String name;
    private int age;
    private String sex;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
        setChanged();
        notifyObservers();
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
        setChanged();
        notifyObservers();
    }

    public String getSex() {
        return sex;
    }

    public void setSex(String sex) {
        this.sex = sex;
        //setChanged();告知数据改变,通过notifyObservers();发送信号通知观察者。
        setChanged();
        notifyObservers();
    }

    @Override
    public String toString() {
        return "MeUser [name=" + name + ", age=" + age + ", sex=" + sex + "]";
    }
}

简简单单设计

目标

给考察的对象,内置抽象观察者集合,定义增加、删除、通知抽象观察者的方式。目标类可以是抽象的也罢得以是切实可行的。如果发生切实的空洞业务要落实,还好分出目标子类

泛观察者

声明了履新数据的法门,由目标调用

现实观察者

兑现了纸上谈兵观察者的翻新数据的法

苟急需目标的组成部分态或者数状态,可能还保持在对目标的援

图片 1

观察者模式-类图.png

可用在同等针对几近的通信及。同时,目标和观察者没有太胜的依靠与涉及,增加还是减小观察者,不会见指向目标导致影响

1.观察者模式介绍

HTTP DNS 解析性能监控

起如此一个现象,我们的运接入了 HTTP DNS,接管了少数接口请求的 DNS
解析。现在某些有统计报告接口,在少数地方,需要 DNS
解析的片段信息,比如解析到的 IP,解析耗时,解析采用的域名服务器地址

我们可以应用观察者来化解这题目

起一个监控器,内置观察者队列,并提供方式来丰富、删除观察者

当 DNS
每次发起一糟解析,把数量统计后,交给监控器。然后监控通知所有观察者拿多少

概念目标类 DnsMonitor

public class DnsMonitor {

    private final List<MonitorWatcher> mWatcherList;

    public DnsMonitor() {
        mWatcherList = new CopyOnWriteArrayList<>();
    }

    @Override
    public void onParseResult(ResolveData data) {
        if (data == null || TextUtils.isEmpty(data.host)) {
            return;
        }

        // 通知观察者们,有解析数据了
        for (MonitorWatcher watcher : mWatcherList) {
            watcher.notifyResolveData(data);
        }
    }

    /**
     * 注册监视者
     */
    public void registerWatcher(MonitorWatcher watcher) {
        mWatcherList.add(watcher);
    }

    /**
     * 注销监视者
     */
    public void unregisterWatcher(MonitorWatcher watcher) {
        mWatcherList.remove(watcher);
    }
}

概念观察者

public interface MonitorWatcher {
    /**
     * 通知获取到的解析数据
     */
    void notifyResolveData(ResolveData data);
}

接下来,我们的有着 DNS 解析器,在解析及结果后,调用的 onParseResult
把多少产生去

可以拿 Monitor
做成单例,或者放置单例内,这样尽管足以通经过都可看。所有的观察者们,只需要实现
MonitorWatcher,然后等着多少通知过来

实则这个功能还有许多细节,比如如何预防唤醒观察者不封堵,还有什么样吃抱有解析器使用和一个监视器。因为和是模式无关,就非列出来了

  • 1.1 最常用之地方是GUI系统、订阅——发布体系等
  • 1.2 重要作用就是是解耦,使得它中的因更粗,甚至形成决不依赖
  • 1.3
    观察者模式同时被叫做发布/订阅模式,观察者模式定义了相同种植同等针对大多的赖关系,让多只观察者对象又监听某一个主题对象。这个主题对象在状态发生变化时,会通报所有观察者对象,使她会自动更新自己。
  • 1.4 举独例:
    就是用csdn这个仿佛于博客的网站来说吧,如果你订阅了要说关注了一个领域,就能够收到这圈子文章的推送,如果无关注,则不可知。是相当给产生一个总控制台(被观察者,持有数据源,这里的数据源是咱每个订阅了底人头)通知下的观察者。

ContentObserver

有这么一个要求,我们纪念要知数据库有数的变型,有同等种结果方法,那便是开个工作线程,去轮询访问。这样的做法会导致资源大量吃

Android 提供的一致栽艺术,称为内容观察者,可以监听数据库变化后会见通报下

比如我们如果监听屏幕亮度的变更,并且做片作业。屏幕亮度变化的数量在系统数据库里,我们可由此
ContentObserver 很轻松地取出

屏幕亮度对应之 Uri 可以如此获得

Settings.System.getUriFor(Settings.System.SCREEN_BRIGHTNESS)

创造观察者

    private static class ScreenBrightnessObserver extends ContentObserver {

        ScreenBrightnessObserver(@NonNull Handler handler) {
            super(handler);
        }

        @Override
        public void onChange(boolean selfChange) {
            super.onChange(selfChange);

            // 亮度发生变化了,可以查询最新的亮度,然后做相应的业务

        }
    }

下一场在页面启动之采用注册

mScreenBrightnessObserver = new ScreenBrightnessObserver(new Handler());
getContentResolver().registerContentObserver(Settings.System.getUriFor(Settings.System.SCREEN_BRIGHTNESS), true, mScreenBrightnessObserver);

每当页面销毁的当儿注销

getContentResolver().unregisterContentObserver(mScreenBrightnessObserver);
  • 案例
  • 证明和截图
  • 模块:新闻,音乐,视频,图片,唐诗宋词,快递,天气,记事本,阅读器等等
  • 接口:七牛,阿里云,天行,干货集中营,极速数据,追书神器等等

定义

观察者模式(Observer
Pattern):定义对象中的均等栽同等针对性几近靠关系,使得在一个对象状态有改变时,其相关依赖对象均落通知并让自动更新

切实世界之模式

按照一些用户订阅了周刊,每次周刊披露的时候还见面送至用户眼前

仍高考的时刻,发送广播通知考试完毕,考生都要停笔,教师要收卷

以打仗之时光,指挥官发命令,战场上的精兵跟军命令决定进攻、撤退、驻守

发出就几乎栽类型

  • 颁布-订阅模式
  • 范-视图模式
  • 源-监听模式
  • 起属者模式
MeUser user=new MeUser();
MeObserver coder1=new MeObserver("name1");
MeObserver coder2=new MeObserver("name2");
MeObserver coder3=new MeObserver("name3");
user.addObserver(coder1);
user.addObserver(coder2);
user.addObserver(coder3);
user.postNewContentToCoder("contentChanged");

EventBus

EventBus 也是观察者模式的一样种植实现

若我们发多单对象,多只观察者,如果每个目标都失去管理观察者列表的话,维护起来挺吓人

从而这边又抽象出一个层次,可以知道呢信息中心,或者信息总线,内部维护着观察者的列表,目标有数变动交给这信息中心展开信息的散发及调度

图片 2

观察者模式-EventBus.png

EventBus
提供了一个那个强劲消息总线,目标发生变化的下,把要通的音封装成一个个音。把信通知受订阅该消息的观察者们

好为此 EventBus
在开模块间的通信。把要通的数量变化封装成事件抛出来。通信的模块没有耦合,发送者不欲了解发生怎样接收者。EventBus
会通知到位

/**
 * Notify any registered observers that the data set has changed.
 * 通知已登记的数据集已更改的任何观察者。
 *
 * <p>This event does not specify what about the data set has changed, forcing
 * any observers to assume that all existing items and structure may no longer be valid.
 * LayoutManagers will be forced to fully rebind and relayout all visible views.</p>
 * 此事件没有指定数据集发生了什么变化,迫使任何观察者假设所有现有的项和结构可能不再有效。
 * LayoutManagers将不得不完全重新绑定和保护所有可见的视图
 */
public final void notifyDataSetChanged() {
    mObservable.notifyChanged();
}

//然后调用此方法
public void notifyChanged() {
    // 遍历所有观察者,并且调用它们的onChanged方法
    for (int i = mObservers.size() - 1; i >= 0; i--) {
         mObservers.get(i).onChanged();
    }
}

观察者模式
目介绍
1.观察者模式介绍
2.观察者使用状况
3.观察者UML图解
4.观察者模式大概实现
4.0 举个例子
4.1 观察者代码
4.2 被观察者代码
4.3 测试代码
4.4 思考
5.观察者模式Android源码分析
5.1 先来看望源代码
5.2 观察者从何来之,查看setAdapter源代码
5.3 观察者在哪里创建的为?如何运作
5.4 代码分析
6.观察者模式深入探索
7.EventBus事件总线
7.1 遇到的问题
7.2 目前风行事件总线框架
7.3 源码解读,单独写成博客呢
7.4 使用手续
8.其他说明
8.1 参考文档:源码设计模式解析

//查看源代码,可以知道
private final RecyclerViewDataObserver mObserver = new RecyclerViewDataObserver();

//查看onchang方法
private class RecyclerViewDataObserver extends AdapterDataObserver {
    @Override
    public void onChanged() {
        assertNotInLayoutOrScroll(null);
        mState.mStructureChanged = true;
        setDataSetChangedAfterLayout();
        if (!mAdapterHelper.hasPendingUpdates()) {
            requestLayout();
        }
    }
}

void setDataSetChangedAfterLayout() {
    if (mDataSetHasChangedAfterLayout) {
        return;
    }
    mDataSetHasChangedAfterLayout = true;
    //获取adapter中数据的数量
    final int childCount = mChildHelper.getUnfilteredChildCount();
    for (int i = 0; i < childCount; i++) {
        final ViewHolder holder = getChildViewHolderInt(mChildHelper.getUnfilteredChildAt(i));
        if (holder != null && !holder.shouldIgnore()) {
  holder.addFlags(ViewHolder.FLAG_ADAPTER_POSITION_UNKNOWN);
        }
    }

    mRecycler.setAdapterPositionsAsUnknown();
    // immediately mark all views as invalid, so prefetched views can be
    // differentiated from views bound to previous data set - both in children, and cache
    markKnownViewsInvalid();
}
  • 4.2 被观察者代码
    • 乃订阅的简书android领域。被观察者:当他出更新时,所有的观察者都见面接到及应的通知

7.EventBus事件总线

  • 事件多级触发场景
  • 超过系统的信息交换场景,如信息队列,事件总线的处理机制
  • 7.1 遇到的题材
    • 当Activity与Fragment中通信,需要出对方的援,会造成耦合性较高。怎么处置呢?
    • 纪念在Activity-B中回调Activity-A的某函数,但是Activity又未克手动创建对象设置一个listener。该怎么惩罚吧?
    • 哪些当service中更新Activity或者fragment的界面也???
  • 7.2 目前风靡事件总线框架
    • EventBus 是异步执行 使用name pattern模式,效率高,但运用未便于
    • Otto 订阅函数不是异步执行
      使用注解,使用方便,但效率比无达标EventBus
    • AndroidEventBus 是异步执行 订阅函数支持tag,使得事件投递更标准
  • 7.3 源码解读
    • 可直接看EventBus源码解析文章
  • 7.4 使用手续
    • 足直接看EventBus源码解析文章

0.本身写的概括案例

  • **5.3 观察者在何创建的呢?如何运转
  • RecycleView是Android中重要性控件,其中adapter刷新数据的adapter.notifyDataSetChanged()就就此到了观察者模式
  • 5.1 先来看望源代码
  • 3.1 关于UML类图
  • 3.2 角色介绍

    • 架空主题(Subject):它将具有观察者对象的援保存到一个汇里,每个主题都足以发外数据之观察者。抽象主题提供一个接口,可以长与去观察者对象。
    • 切切实实主题(ConcreteSubject):将关于状态存入具体观察者对象;在切实主题中状态改变时,给所有登记了的观察者发出通报。
    • 架空观察者(Observer):为富有的现实观察者定义一个接口,在得主题通知时更新自己。
    • 具体观察者(ConcreteObserver):实现抽象观察者角色所要求的创新接口,以便要自身的状态与主题状态协调。
  • 3.3 其他验证

    • 1.Subject 及 Observer 是一个一针对性几近之涉嫌,也就是说观察者而实现
      Observer 接口并把团结注册及 Subject 中就会接及消息事件;
    • 2.Java API来坐的观察者模式类似:java.util.Observable 类和
      java.util.Observer 接口,这分别指向承诺着 Subject 和 Observer
      的角色;
    • 3.用到 Java API 的观察者模式类,需要注意的是为观察者在调用
      notifyObservers() 函数通知观察者之前一定要是调用 setChanged()
      函数,要不然观察者无法收到通报;
    • 4.行使 Java API 的通病也甚显眼,由于 Observable 是一个好像,java
      只同意单继承的弱点就是招你一旦以想使获得其它一个父类的习性时,你只能选择适配器模式要是外项目的艺术,而且由于
      setChanged() 函数为 protected 属性,所以您只有继承 Observable
      类,否则你根本无法使用该类的性,这吗违背了设计模式的标准:多为此做,少用持续。

6.观察者模式深入探讨

public class MeObserver implements Observer {

    private String yourName;
    public MeObserver(String yourName){
        this.yourName=yourName;
    }
    @Override
    public void update(Observable o, Object arg) {
        System.out.println("你订阅的"+arg.toString()+"更新了。");
    }
    @Override
    public String toString() {
        return "your name "+yourName;
    }
}

  • 5.2 观察者从乌来的,查看setAdapter源代码

另外验证

  • 4.3 测试代码
    • 一定给服务器更新通知
  • 4.4
    思考:为什么观察者是落实一个observer接口,而于观察者是继往开来一个虚幻类为

    • 吃观察者写成抽象类的因是复用,观察者写成接口的故是跌代码的耦合度,面向接口编程,在规则里就是是乘倒置原则,我们倒着思想,如果这里不是接口,而是一个现实的近乎,那么,耦合度就一定强了,如果不是观察者注册就无法填补加至observable里,就要修改observable的代码

4.观察者模式大概实现

![](https://upload-images.jianshu.io/upload_images/4432347-27bf2c97c86c7c77.png)

Image.png

  • 知乎:https://www.zhihu.com/people/yang-chong-69-24/pins/posts
  • 领英:https://www.linkedin.com/in/chong-yang-049216146/
  • 简书:http://www.jianshu.com/u/b7b2c6ed9284
  • csdn:http://my.csdn.net/m0\_37700275
  • 网易博客:http://yangchong211.blog.163.com/
  • 新浪博客:http://blog.sina.com.cn/786041010yc
  • github:https://github.com/yangchong211
  • 喜马拉雅听书:http://www.ximalaya.com/zhubo/71989305/
  • 脉脉:yc930211
  • 360图书馆:http://www.360doc.com/myfiles.aspx
  • 开源中国:https://my.oschina.net/zbj1618/blog
  • 泡在网上的光阴:http://www.jcodecraeer.com/member/content\_list.php?channelid=1
  • 邮箱:yangchong211@163.com
  • 阿里云博客:https://yq.aliyun.com/users/article?spm=5176.100239.headeruserinfo.3.dT4bcV
  • 5.4 代码分析
  • 每当Adapter里面有一个AdapterDataObservable,是为观察者,被观察者必须有三个法子,注册,销毁,通知,这里的登记就是registerAdapterDataObserver,通知就是notify相关的。
  • 每当setAdapter的时光,将观察者,也尽管是RecyclerViewDataObserver注册到AdapterDataObservable里面来保护,观察者里面自然是创新布局。
  • 俺们调用notifyDataSetChanged其实就是调用被观察者的notify相关方法

5.观察者模式Android源码分析

  • 4.0 举个例子
    • 尽管以csdn这个近乎于博客的网站的话吧,如果您订阅了还是说关注了一个天地,就可知接受此小圈子文章的推送,如果没关注,则未克。是一定给有一个总控制台(被观察者,持有数据源,这里的数据源是我们每个订阅了的总人口)通知下的观察者。
  • 4.1 观察者代码**
    • 观察者,也就算是若【程序员】,订阅专题的人

3.观察者UML图解

public void setAdapter(Adapter adapter) {
    // bail out if layout is frozen
    setLayoutFrozen(false);
    setAdapterInternal(adapter, false, true);
    requestLayout();
}

private void setAdapterInternal(Adapter adapter, boolean compatibleWithPrevious,boolean removeAndRecycleViews) {
    //如果有adapter,那么先注销对应观察者
    if (mAdapter != null) {
        mAdapter.unregisterAdapterDataObserver(mObserver);
        mAdapter.onDetachedFromRecyclerView(this);
    }

    if (!compatibleWithPrevious || removeAndRecycleViews) {
        removeAndRecycleViews();
    }
    //重置
    mAdapterHelper.reset();
    final Adapter oldAdapter = mAdapter;
    mAdapter = adapter;
    if (adapter != null) {//将观察者注册到adapter中
        adapter.registerAdapterDataObserver(mObserver);
        adapter.onAttachedToRecyclerView(this);
    }
    if (mLayout != null) {
        mLayout.onAdapterChanged(oldAdapter, mAdapter);
    }

    mRecycler.onAdapterChanged(oldAdapter, mAdapter, compatibleWithPrevious);
    mState.mStructureChanged = true;
    markKnownViewsInvalid();
}

2.观察者使用状况

相关文章