Android -- 每日一问:回调函数和观察者模式的区别?

news/2024/11/8 0:16:01/

知识点

观察者模式

网上很容易查到观察者模式的定义:
观察者模式定义了对象间的一种一对多依赖关系,使得每当一个对象改变状态,则所有依赖于它的对象都会得到通知并被自动更新。

Android中大量的使用了观察者模式。你可能已经用过ListView的adapter.notifyDataSetChanged来触发ListView的列表界面进行更新。notifyDataSetChanged的内部实现就是基于观察者模式。

image.png

跟进这段代码你会发现:BaseAdapter中的DataSetObserver(观察者)实现Observer接口,DataSetObservable(被观察者)继承Observable类。

标准的观察者模式的写法应该照下面的UML图:

image.png

有几个概念(抽象主题(Subject)、具体主题(ConcreteSubject)、抽象观察者(Observer)和具体观察者(ConcreteObserver)),好在Java帮我实现了相关的代码,可以通过Observable类和Observer接口实现了观察者模式。Observer对象是观察者,Observable对象是被观察者。

还有EventBus, RxJava等常见的开源库也是居于观察者模式设计的,只是它们实现的方式各有不同。

回调函数
那回调函数和这又有什么关系呢?看看这段再熟悉不过的代码片段:

        button.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {// do something}});

View的Listener监听会通过setOnClickListener给View传递一个Listener对象,当相关的事件发生时是触发onClick(回调onClick)。这其实也是一种观察者模式,OnClickListener是观察者,View是被观察者,当View收到Click事件是会通知观察者执行onClick()。

参考回答

观察者模式定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象。观察者模式完美的将观察者和被观察的对象分离开,一个对象的状态发生变化时,所有依赖于它的对象都得到通知并自动刷新。
回调函数其实也算是一种观察者模式的实现方式,回调函数实现的观察者和被观察者往往是一对一的依赖关系。
所以最明显的区别是观察者模式是一种设计思路,而回调函数式一种具体的实现方式;另一明显区别是一对多还是多对多的依赖关系方面。

更多面试题

面试题:Android的单列模式如何保证一定单列的情况?

分析:如下代码,我们一般写单列模式是这样的:

public class Singleton{private static Singleton instance;private Singleton() {};public static Singleton getInstance() {if (instance==null)instance=new Singleton();return instance;}
}

如果不同的线程同时执行“if (instance==null)”,因为instance还未赋值,是会存在多个instance实例的。所以保险的一点的写法:

public class Singleton{private static Singleton instance;private Singleton() {};public static Singleton getInstance() {if (instance==null) {synchronized(Singleton.class) {if (instance==null)instance=new Singleton();}}return instance;}
}

但这种两次判断的方式还是有可能出问题。因为“instance=new Singleton();”这段代码并不是一条唯一的指令,实际上这段代码会编译成多条指令,大致上做了3件事:
(1)给Singleton实例分配内存
(2)调用Singleton()构造函数,初始化成员字段
(3)将instance对象指向分配的内存

而且上面的(2)和(3)的顺序无法得到保证的,虚拟机可能先初始化实例字段再把instance指向具体的内存实例,也可能先把instance指向内存实例再对实例进行初始化成员字段。

当然这请情况很少见,不过我还是听一个同事讲过,他有遇到了用这种两次判断的方法还是有多个实例。

参考回答:我们可以在两次判断的基础上,使用“volatile”关键字来修饰instance,保证instance实例的唯一。

public class Singleton{private volatile static Singleton instance;private Singleton() {};public static Singleton getInstance() {if (instance==null) {synchronized(Singleton.class) {if (instance==null)instance=new Singleton();}}return instance;}
}

面试题: Android较常用到的设计模式?

参考回答:

  • 适配器模式:GridView、ListView的Adapter;
  • 建造者模式:AlertDialog.Builder;
  • 观察者模式:ListView的adapter.notifyDataSetChanged;
  • 责任链模式:View的事件分发;

你的朋友是不是也在准备面试呢?你可以把今天的题目分享给好友,或许你可以帮到他。


http://www.ppmy.cn/news/3597.html

相关文章

Java+Servlet电商购物系统(含源码+论文+答辩PPT等)

项目功能简介: 本项目含代码详细讲解视频,手把手带同学们敲代码从0到1完成项目 该项目采用技术MyBatis、Tomcat服务器、MySQL数据库 项目含有源码、配套开发软件、软件安装教程、项目发布教程。 项目涉及的技术: 1、前端:JSP、css、Javascrip…

水果FLStudio21.0.0软件最新版有哪些新增功能变化?

FL Studio(水果软件)21 引入更快、更精确的音频编辑、改进的内容发现、对 DAW 情绪的控制以及更多鼓舞人心的创意工具。FL Studio是一款功能非常强大的音乐创作编辑软件它就是FL Studio(水果软件)。使用FL Studio中文版可以轻松帮我们制作自己的音乐唱片,拥有强大且…

【操作系统】模式切换篇

CPU的模式 什么是CPU的模式?这和CPU的发展过程有关,最开始CPU是8位的,后来发展到16位,然后是32位,现在是64位,多少多少位指的是寄存器的位宽。CPU能使用的寄存器宽度以及CPU使用的指令等就构成了CPU的模式…

Python使用Selenium Webdriver爬取网页所有内容

Python使用Selenium Webdriver爬取网页所有内容一、为什么我抓不到网页的全部html内容二、Selenium的基本使用三、使用Selenium抓取全部HTML一、为什么我抓不到网页的全部html内容 有时候,我们在用urllib或者requests库抓取页面时,得到的html源代码和浏…

Sysmac Studio使用Tortoise和Git实现版本控制

Sysmac Studio使用Tortoise和Git实现版本控制 实验时间:2022/11/16 实验软件:Sysmac Studio(1.52,需要软件授权支持版本控制)、Git(2.38.1)、Tortoise(2.13.0)、gitee(代码仓库) 实验目的:Sysmac Studio实现版本控制、多人同时开发(需要有Git和tortoris使用基础) 实验…

endo BCN-PEG4-COOH,1881221-47-1,endo BCN-四聚乙二醇-羧酸特点分享

●外观以及性质: endo BCN-PEG4-acid含有BCN基团和羧酸基团,酸基团可以在偶联条件下与胺反应形成酰胺键。BCN基团可以发生点击化学反应。 【产品理化指标】: ●中文名:endo BCN-四聚乙二醇-羧酸 ●英文名:endo BCN-P…

C语言文件操作(1)

个人主页:平行线也会相交 欢迎 点赞👍 收藏✨ 留言✉ 加关注💓本文由 平行线也会相交 原创 收录于专栏【C/C】 目录什么是文件程序文件数据文件文件名文件类型文件缓冲区文件指针什么是文件 磁盘的文件是文件 但在程序设计中,我…

特征融合与灰色回归的滚动轴承性能退化评估

摘要 针对传统退化指标无法准确反映滚动轴承全寿命周期内退化状态的问题,提出一种特征融合与灰色回归的滚动轴承性能退化评估方法.该方法提取滚动轴承振动信号的高维退化特征,构建基于单调性、相关性和鲁棒性的综合评价准则,选择有效退化特征并构建敏感指标集;提出核独立成…