原文地址 http://blog.csdn.net/qq_25806863/article/details/69218968

观察者模式是一种使用频率非常高的设计模式,最常用的地方就是订阅-发布系统。

这个模式的重要作用就是将观察者和被观察者解耦,使他们之间的依赖更小甚至没有。

定义
定义对象一种一对多的依赖关系,使得每当一个对象改变状态,则所有依赖于他的对象都会得到通知并被自动更新。

使用场景
关联行为场景,这个关联是可拆分的。将观察者和被观察者封装在不同的对象中,可以各自独立的变化。
当一个对象改变时,有其他对象要进行相应的变化,但是他并不知道有多少个对象需要变化。
跨系统的消息交换长江,如消息队列,时事件总线等
UML

Subject : 抽象被观察者(Observeable),吧所有观察者对象的医用保存在一个集合里,每个主题都可以有任意数量的观察者,抽象被观察者提供一个接口,可以增加和删除观察者对象。
ConcreteSubject: 具体的被观察者,将有关状态存入具体的观察者对象,在具体的被观察者内部状态发生变化时,给所有注册的观察者发送通知。
Observer : 抽象观察者,定义了一个更新接口,使得在得到被观察者的通知时更新自己。
ConcreteObserver : 具体的观察者,实现了抽象观察者锁定义的接口,用来在收到通知时更新自己。
简单实现
订阅模式就是个观察者模式,订阅后,被订阅的有更新就会提示你。

拿微信公众号举个例子吧.Java提供的有Observer和Observable类,可以很方便的实现观察者模式。

先定义一个订阅者,实现更新方法。
---------------------
作者:喵了个呜s
来源:CSDN
原文:https://blog.csdn.net/qq_25806863/article/details/69218968
版权声明:本文为博主原创文章,转载请附上博文链接!

public class User implements Observer {public String name;public User(String name) {this.name = name;}@Overridepublic void update(Observable o, Object arg) {System.out.println("Hi "+name +",公众号更新了内容:"+arg);}
}

定义一个可观察者,有变化时发布更新通知。

public class Gamedaily extends Observable {public void postNewArticle(String content){//内容发生改变
        setChanged();//通知所有订阅者改变的内容
        notifyObservers(content);}
}

使用

public class Client {public static void main(String[] args) {Gamedaily gamedaily = new Gamedaily();User user1 = new User("user1");User user2 = new User("user2");User user3 = new User("user3");//将观察者注册到可观察者的通知列表中。
        gamedaily.addObserver(user1);gamedaily.addObserver(user2);gamedaily.addObserver(user3);gamedaily.postNewArticle("新文章来了");}
}

输出

当公众号发布新文章的时候,所有订阅者都收到的通知,并作出相应的改变。一个公众号对应多个订阅者,并且完全没有耦合。

Android源码中的观察者模式
通常在ListView的内容变化时,我们会调用notifyDataSetChanged()这个方法,然后ListView里面的数据就会进行更新。这个感觉就像是观察者模式。ListView在观察者内容,内容变化发布通知之后ListView就会更新数据。

看一下这个方法。

package android.widget;
public abstract class BaseAdapter implements ListAdapter, SpinnerAdapter {private final DataSetObservable mDataSetObservable = new DataSetObservable();public void registerDataSetObserver(DataSetObserver observer) {mDataSetObservable.registerObserver(observer);}public void unregisterDataSetObserver(DataSetObserver observer) {mDataSetObservable.unregisterObserver(observer);}......public void notifyDataSetChanged() {mDataSetObservable.notifyChanged();}......
}

这段代码可以看到这应该是一个观察者模式,而且这个一个被观察者,里面提供了注册和注销观察者以及通知观察者的方法。

这些方法是通过DataSetObservable这个类调用的:

package android.database;
public class DataSetObservable extends Observable<DataSetObserver> {   public void notifyChanged() {synchronized(mObservers) {for (int i = mObservers.size() - 1; i >= 0; i--) {mObservers.get(i).onChanged();}}}......
}

这个类继承自Observable,Observable中有一个protected final ArrayList<T> mObservers = new ArrayList<T>();,
用来保存注册的观察者。mDataSetObservable.registerObserver(observer)和mDataSetObservable.unregisterObserver(observer)分别就是增加和删除。在notifyChanged方法中,循环这个集合,调用每一个观察者的onChanged()方法。那么这些观察者是什么时候注册的呢?也就是ListView和Adapter什么时候成了订阅关系。在ListView的setAdapter()中
public class ListView extends AbsListView {public void setAdapter(ListAdapter adapter) {//如果已经有了一个adapter,注销这个adapter之前的观察者,if (mAdapter != null && mDataSetObserver != null) {mAdapter.unregisterDataSetObserver(mDataSetObserver);}......if (mHeaderViewInfos.size() > 0|| mFooterViewInfos.size() > 0) {mAdapter = wrapHeaderListAdapterInternal(mHeaderViewInfos, mFooterViewInfos, adapter);} else {//将新的adapter赋给mAdaptermAdapter = adapter;}......super.setAdapter(adapter);if (mAdapter != null) {mAreAllItemsSelectable = mAdapter.areAllItemsEnabled();//保存之前的数据个数mOldItemCount = mItemCount;//获取新的个数mItemCount = mAdapter.getCount();checkFocus();//创建数据集观察者mDataSetObserver = new AdapterDataSetObserver();//注册观察者
            mAdapter.registerDataSetObserver(mDataSetObserver);...}} else {...}requestLayout();}
}

AdapterDataSetObserver是ListView的父类AbsListView的内部类

package android.widget;
public abstract class AbsListView extends AdapterView<ListAdapter> implements TextWatcher,ViewTreeObserver.OnGlobalLayoutListener, Filter.FilterListener,ViewTreeObserver.OnTouchModeChangeListener,RemoteViewsAdapter.RemoteAdapterConnectionCallback {class AdapterDataSetObserver extends AdapterView<ListAdapter>.AdapterDataSetObserver {@Overridepublic void onChanged() {super.onChanged();if (mFastScroll != null) {mFastScroll.onSectionsChanged();}}······}
}

AdapterDataSetObserver是AdapterView.AdapterDataSetObserver的子类,所以要看super.onChanged()

package android.widget;
public abstract class AdapterView<T extends Adapter> extends ViewGroup {class AdapterDataSetObserver extends DataSetObserver {private Parcelable mInstanceState = null;@Overridepublic void onChanged() {mDataChanged = true;mOldItemCount = mItemCount;mItemCount = getAdapter().getCount();// Detect the case where a cursor that was previously invalidated has// been repopulated with new data.if (AdapterView.this.getAdapter().hasStableIds() && mInstanceState != null&& mOldItemCount == 0 && mItemCount > 0) {AdapterView.this.onRestoreInstanceState(mInstanceState);mInstanceState = null;} else {rememberSyncState();}checkFocus();//重新布局
            requestLayout();}......}
}

整理一下:当ListView数据变化时,调用Adapter的notifyDataSetChange方法,这个方法调用DataSetObservable的notifyChanged方法,这个方法又会调用所有观察者的onChanged方法,onChanged再调用重新布局View的方法,完成刷新数据的功能。

总结
优点
解除了观察者和被观察者的耦合,而且依赖的都是抽象,容易应对业务变化,各自的变化都不会影响另一个。
增强系统灵活性、可拓展性。
缺点
Java中的消息默认是顺序执行,如果一个观察者卡顿,会造成整个系统效率变低,可以考虑异步。
可能会引起无用的操作甚至错误的操作。

转载于:https://www.cnblogs.com/Im-Victor/p/6305976.html

Android设计模式-观察者模式相关推荐

  1. Android 设计模式 - 观察者模式

    最近在看「Head First 设计模式」,感觉收获很大,对架构设计有了更深的理解.我会陆续记录读后的心得,并进行编码实践,强化理解. 观察者模式是常用的设计模式之一,它的定义是这样的: 观察者模式定 ...

  2. Android设计模式——单例模式(Singleton)

    二十三种设计模式分为三大类: 创建型模式,共五种:工厂方法模式.抽象工厂模式.单例模式.建造者模式.原型模式. 结构型模式,共七种:适配器模式.装饰器模式.代理模式.外观模式.桥接模式.组合模式.享元 ...

  3. java/android 设计模式学习笔记目录

    其实很早就想开始总结设计模式了,无奈刚刚换完工作,工作太忙,平时周末也太懒,难得提起精神写一点,估计时间会花的很长,不过还是自己加油吧~~. 学习笔记,顾名思义,其实就是我在平时看书,工作的笔记而已, ...

  4. Android设计模式与应用场景

    文章目录 Android 设计模式 1.设计模式的分类 1.1 创建型模式(5种) [单例模式] : [抽象工厂模式]: [工厂方法模式]: [原型模式]: [建造者模式]: 1.2 结构型模式(七种 ...

  5. java/android 设计模式学习笔记(1)--- 单例模式

    前段时间公司一些同事在讨论单例模式(我是最渣的一个,都插不上嘴 T__T ),这个模式使用的频率很高,也可能是很多人最熟悉的设计模式,当然单例模式也算是最简单的设计模式之一吧,简单归简单,但是在实际使 ...

  6. Python设计模式-观察者模式

    Python设计模式-观察者模式 代码基于3.5.2,代码如下; #coding:utf-8 # 观察者设计模式class observerInterface():def update(self,va ...

  7. [Head First设计模式]山西面馆中的设计模式——观察者模式

    原文:[Head First设计模式]山西面馆中的设计模式--观察者模式 系列文章 [Head First设计模式]山西面馆中的设计模式--装饰者模式 引言 不知不自觉又将设计模式融入生活了,吃个饭也 ...

  8. java设计模式--观察者模式(Observer)

    java设计模式--观察者模式(Observer) java设计模式--观察者模式(Observer) 观察者模式的定义: 定义对象间的一种一对多的依赖关系.当一个对象的状态发生改变时,所有依赖于它的 ...

  9. 【学习笔记】ABAP OOD设计模式 - 观察者模式

    ABAP OOD设计模式 - 观察者模式 整理转自-<SAP ABAP 面向对象程序设计(原则.模式及实践)> 定义对象间的一对多的依赖关系,当一个对象的状态发生改变时,这个对象相关依赖的 ...

最新文章

  1. 人人出售56不亏:三方得利
  2. 在Cisco交换机上实现隔离访问
  3. 27-----BBS论坛
  4. verilog入门笔记
  5. ubuntu连接有线局域网后无法使用无线网卡上网
  6. Linux修改密码后不能SSH远程登录了
  7. WCF学习(五)数据契约之已知类型
  8. java获取运行时对象,java 面向对象(四十一):反射(五)反射应用二:获取运行时类的完整结构...
  9. 直接访问 可以拿到cookie 本地起的服务拿不到 cookie_微服务下的分布式session管理...
  10. 数据库触发器调用python_从mysql触发器调用python脚本
  11. 知客CRM成功客户专访----厦门英斯捷
  12. 【数据】社区发现数据集
  13. matlab解决力学问题程序,力学专业程序实践:用MATLAB解决力学问题的方法与实例...
  14. Ask and Answer
  15. 粉丝经济大爆发居然真的来了
  16. codeforces 348A Mafia
  17. 有关计算机英语作文素材,英语写作素材
  18. php宠物网站源代码,PHP响应式中英双语宠物医院网站整站源码(自适应手机移动端) dedecms内核...
  19. uniapp开发环境搭建
  20. Web项目之人力资源管理系统

热门文章

  1. ×××S 2012 参照函数 -- 介绍
  2. 【转】JAVA 接口
  3. 体绘制(Volume Rendering)概述介绍
  4. js之argument小解
  5. 20181113-3 Beta阶段贡献分配规则
  6. 【quickhybrid】架构一个Hybrid框架
  7. 小程序的事件处理参数不能取得
  8. 什么样的代码为好代码?好代码的科学定义
  9. 在Horizon Workspace中配置Windows单点登录-进阶篇
  10. mysql通过中间表实现数据的“部分复制”