当前位置: 首页 > article >正文

安卓开发用到的设计模式(3)行为型模式

安卓开发用到的设计模式(3)行为型模式

文章目录

  • 安卓开发用到的设计模式(3)行为型模式
    • 1. 命令模式(Command Pattern)
    • 2. 策略模式(Strategy Pattern)
    • 3. 观察者模式(Observer Pattern)
    • 4. 模板方法模式(Template Method Pattern)
    • 5. 责任链模式(Chain of Responsibility Pattern)
    • 6. 状态模式(State Pattern)
    • 7. 访问者模式(Visitor Pattern)
    • 8. 中介者模式(Mediator Pattern)
    • 9. 迭代器模式(Iterator Pattern)
    • 10. 备忘录模式(Memento Pattern)
    • 11. 解释器模式(Interpreter Pattern)

本文首发地址 https://h89.cn/archives/399.html

1. 命令模式(Command Pattern)

命令模式将一个请求封装成一个对象,从而使你可用不同的请求对客户进行参数化,对请求排队或记录请求日志,以及支持可撤销的操作。

在Android中的主要应用场景:

  1. 点击事件处理

    • OnClickListener就是一个典型的命令模式实现。例如,一个按钮的点击事件可以被封装成一个Command对象,当按钮被点击时,执行该Command对象的execute()方法。
    • 将点击事件封装成命令对象,使得事件处理逻辑与UI组件解耦,方便进行单元测试和复用。
  2. 异步任务处理

    • AsyncTask和Handler消息机制。在AsyncTask中,doInBackground()方法封装了需要在后台执行的任务(命令),而onPostExecute()等方法则处理任务执行后的结果。Handler消息机制中的Message对象也可以看作是一种命令,包含了需要处理的数据和逻辑。
    • 将任务封装成命令,实现异步执行、任务排队、取消等操作,提高应用的响应性。

2. 策略模式(Strategy Pattern)

策略模式定义了一系列算法,并将每个算法封装起来,使它们可以相互替换,且算法的变化不会影响到使用算法的客户。

在Android中的主要应用场景:

  1. 动画实现

    • 不同的动画插值器(Interpolator)。例如,LinearInterpolator、AccelerateInterpolator等实现了不同的动画速率变化算法,可以在运行时根据需求选择不同的插值器来改变动画效果。
    • 可以动态切换动画效果,使得动画行为更加灵活。
  2. 图片加载策略

    • 不同的图片加载方式(网络、本地、缓存)。例如,使用Glide、Picasso等图片加载库时,可以配置不同的加载策略(如只从缓存加载、优先从网络加载等),根据网络状态或用户设置动态切换。
    • 根据需求切换加载策略,优化图片加载性能和用户体验。

3. 观察者模式(Observer Pattern)

观察者模式定义了对象之间的一对多依赖,当一个对象状态改变时,其所有依赖者都会收到通知并自动更新。

在Android中的主要应用场景:

  1. 事件总线

    • EventBus、RxBus等事件传递机制。发布者(Subject)在某个事件发生时通知所有订阅者(Observer),订阅者执行相应的处理逻辑。这使得不同组件之间可以通过事件进行通信,而无需直接引用,降低耦合度。
    • 实现组件间的解耦通信,提高代码的可维护性和可扩展性。
  2. 数据绑定

    • LiveData、DataBinding。LiveData作为可观察的数据持有者,当其数据发生变化时,会自动通知所有观察者(通常是UI组件),从而实现数据与UI的自动同步更新。DataBinding则进一步简化了这一过程。
    • 实现数据与UI的自动同步,减少手动更新UI的代码,提高开发效率。

4. 模板方法模式(Template Method Pattern)

模板方法模式定义一个操作中的算法骨架,而将某些步骤延迟到子类中实现。

在Android中的主要应用场景:

  1. Activity生命周期

    • onCreate、onStart、onResume等生命周期方法。Android框架定义了Activity生命周期的骨架,开发者通过重写这些模板方法来插入自定义的逻辑,例如在onCreate()中进行初始化,在onResume()中恢复状态等。
    • 提供固定的执行流程框架,确保Activity在不同状态下执行必要的初始化、暂停、恢复和销毁操作。
  2. AsyncTask

    • doInBackground、onPreExecute、onPostExecute等模板方法。AsyncTask定义了异步任务执行的骨架,doInBackground()是必须由子类实现的抽象方法,用于执行后台耗时操作;onPreExecute()和onPostExecute()是可选重写的方法,用于在任务执行前后更新UI。
    • 规范异步任务的执行流程,简化了在后台线程执行任务并在主线程更新UI的复杂性。

5. 责任链模式(Chain of Responsibility Pattern)

责任链模式为请求创建了一个接收者对象的链,使多个对象都有机会处理请求。请求沿着这条链传递,直到有一个对象处理它为止。每个接收者都包含对下一个接收者的引用。

在Android中的主要应用场景:

  1. 事件分发机制

    • View的事件分发流程。当触摸事件发生时,事件会沿着View树从父View向子View传递。每个View或ViewGroup都可以选择拦截(处理)事件或将其传递给下一个接收者(子View或父View),形成一个责任链。
    • 实现触摸事件的层级传递,每个View或ViewGroup都可以选择处理或传递事件,灵活控制事件的响应。
  2. 拦截器链

    • OkHttp的拦截器链。OkHttp通过拦截器链来处理网络请求,每个拦截器负责处理请求的某个方面(如日志记录、缓存、重定向等)。请求在链中依次传递,每个拦截器执行其逻辑后再将请求传递给下一个拦截器,直到最终发送请求并处理响应。
    • 实现网络请求的处理流程,每个拦截器都可以在请求发送前或响应接收后进行处理或修改,方便实现各种网络功能。

6. 状态模式(State Pattern)

状态模式允许一个对象在其内部状态改变时改变它的行为。对象看起来似乎修改了它的类。

在Android中的主要应用场景:

  1. 播放器状态管理

    • 播放、暂停、停止、缓冲等状态切换。媒体播放器根据当前状态(如Idle、Initialized、Prepared、Started、Paused、Stopped、PlaybackCompleted等)来改变其行为和UI表现。例如,在播放状态显示暂停按钮,在暂停状态显示播放按钮。
    • 不同状态下的UI展示和操作响应,使得播放器的行为符合用户预期。
  2. 网络连接状态

    • 在线、离线、正在连接等状态处理。应用可以根据当前的网络连接状态(如通过ConnectivityManager获取)来调整功能可用性或UI提示。例如,在离线状态下禁用某些需要网络的功能,或显示“无网络连接”的提示。
    • 根据状态调整应用行为,提供更好的用户体验和错误处理。

7. 访问者模式(Visitor Pattern)

访问者模式表示一个作用于某对象结构中的各元素的操作,它使你可以在不改变各元素的类的前提下定义作用于这些元素的新操作。

在Android中的主要应用场景:

  1. View树遍历

    • 实现自定义View的遍历操作。例如,可以使用访问者模式遍历一个ViewGroup中的所有子View,并对特定类型的View执行操作(如修改属性、收集信息等),而无需在ViewGroup类中硬编码这些操作。
    • 收集或修改View树中的特定元素,提高View树操作的灵活性和可扩展性。
  2. 数据结构访问

    • 对复杂数据结构的统一处理。例如,如果有一个包含多种不同类型对象的列表,可以使用访问者模式定义不同的访问者来处理不同类型的对象,而无需修改这些对象的类。这在处理XML、JSON等结构化数据时很有用。
    • 实现数据的格式转换和导出,方便对不同类型的数据进行统一处理。

8. 中介者模式(Mediator Pattern)

中介者模式用一个中介对象来封装一系列的对象交互,使各对象不需要显式地相互引用,从而使其耦合松散。

在Android中的主要应用场景:

  1. Fragment通信

    • Activity作为中介者协调多个Fragment。在多Fragment的应用中,Fragment之间不应直接通信,而是通过宿主Activity作为中介。Fragment将消息发送给Activity,Activity再将消息转发给目标Fragment,从而降低Fragment之间的耦合。
    • 处理Fragment之间的数据传递和交互,使各Fragment保持独立。
  2. MVVM架构

    • ViewModel作为中介者。在MVVM(Model-View-ViewModel)架构中,ViewModel充当View(Activity/Fragment)和Model(数据层)之间的中介。View通过ViewModel暴露的数据和命令与Model交互,Model的变化通过ViewModel通知View,避免View直接依赖Model。
    • 协调View和Model之间的交互,实现View和Model的解耦。

9. 迭代器模式(Iterator Pattern)

迭代器模式提供一种方法顺序访问一个聚合对象中的各个元素,而又不暴露其内部的表示。

在Android中的主要应用场景:

  1. 集合遍历

    • Cursor对数据库查询结果的遍历。Cursor提供了一种顺序访问数据库查询结果集的方式,而无需一次性加载所有数据到内存,隐藏了底层数据存储的细节。
    • RecyclerView.Adapter的数据访问。Adapter通过getItemCount()、getItemViewType()、onBindViewHolder()等方法,以迭代器的方式访问和展示数据集合中的元素,而无需关心数据集合的具体实现。
    • 提供一种方法顺序访问一个聚合对象中的各个元素,而又不暴露其内部的表示。
  2. 分页加载

    • 实现数据的分页加载机制。例如,在列表或网格视图中,可以使用迭代器模式按页加载数据,每次只从数据源获取并展示一部分数据,提高性能和用户体验。
    • 管理大量数据的遍历和展示,尤其适用于需要分批加载的场景。

10. 备忘录模式(Memento Pattern)

备忘录模式在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态,以便以后当需要时能将该对象恢复到原先保存的状态。

在Android中的主要应用场景:

  1. Activity状态保存

    • onSaveInstanceState保存状态。当Activity因配置改变或系统资源不足而被销毁时,可以通过onSaveInstanceState()方法将当前状态(如EditText中的文本、滚动位置等)保存到Bundle对象中。
    • onCreate恢复保存的状态。在Activity重建时,可以在onCreate()方法中从Bundle对象中恢复之前保存的状态,使用户感觉Activity没有中断。
    • 在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态,以便以后当需要时能将该对象恢复到原先保存的状态。
  2. 编辑器撤销/重做

    • 保存编辑操作历史。在文本编辑器等应用中,每次用户执行一个编辑操作(如插入、删除文本),都可以将当前文档的状态或操作本身保存为一个备忘录对象。
    • 实现操作的撤销和重做。通过管理这些备忘录对象,可以轻松地将文档恢复到之前的某个状态(撤销)或重新应用某个操作(重做)。

11. 解释器模式(Interpreter Pattern)

解释器模式给定一个语言,定义它的文法的一种表示,并定义一个解释器,这个解释器使用该表示来解释语言中的句子。

在Android中的主要应用场景:

  1. 表达式计算器

    • 解析和计算数学表达式。例如,实现一个简单的计算器应用,可以使用解释器模式将用户输入的数学表达式(如"2 + 3 * 5")解析成抽象语法树,然后通过解释器遍历语法树并计算结果。
    • 自定义公式解析器,方便处理各种复杂的表达式。
  2. 自定义配置解析

    • 解析特定格式的配置文件。如果应用使用自定义格式的配置文件,可以定义一套文法规则和解释器来解析配置文件内容,并将其转换为应用内部的数据结构或配置对象。
    • 处理自定义的领域特定语言(DSL),使得配置或脚本更加灵活和强大.

这些行为型设计模式在Android开发中的应用不仅能够提高代码的复用性和可维护性,还能使代码结构更加清晰。通过合理使用这些模式,我们可以更好地组织代码,提高开发效率,并且使应用程序更容易维护和扩展。在实际开发中,我们应该根据具体场景选择合适的设计模式,避免过度设计,确保代码的简洁性和可读性。


相关系列文章:

  • 安卓开发用到的设计模式(1)创建型模式
  • 安卓开发用到的设计模式(2)结构型模式
  • 安卓开发用到的设计模式(3)行为型模式

相关文章:

安卓开发用到的设计模式(3)行为型模式

安卓开发用到的设计模式(3)行为型模式 文章目录 安卓开发用到的设计模式(3)行为型模式1. 命令模式(Command Pattern)2. 策略模式(Strategy Pattern)3. 观察者模式(Observ…...

生成模型:从数据学习到创造的 AI 新范式

一、生成模型:定义与核心逻辑 生成模型是一类通过学习数据潜在分布来创造新样本的机器学习模型。其核心目标是构建数据的概率分布模型 P(X),使生成的样本 X^ 与真实数据 X 具有相似的统计特征。 1.1 与判别模型的本质区别 维度生成模型判别模型核心目…...

尚硅谷redis7 90-92 redis集群分片之集群扩容

90 redis集群分片之集群扩容 三主三从不够用了,进行扩容变为4主4从 问题:1.新建两个redis实例,怎么加入原有集群?2.原有的槽位分3段,又加进来一个槽位怎么算? 新建6387、6388两个服务实例配置文件新建后启…...

RabbitMQ性能调优:关键技术、技巧与最佳实践

RabbitMQ作为一款高可靠、高扩展性的消息中间件,其性能表现直接影响到分布式系统的吞吐量和响应延迟。本文基于RabbitMQ官方文档和最佳实践,结合核心性能优化方向,详细探讨RabbitMQ性能调优的关键技术、技巧和策略。 通过以下优化策略&#…...

系统架构中的组织驱动:康威定律在系统设计中的应用

康威定律(Conway’s Law) 是由计算机科学家 Melvin Conway 在1967年提出的理论,其核心观点是:“系统的架构设计会不可避免地反映其开发组织的沟通结构。换句话说,软件系统的结构会与构建它的团队的组织结构高度相似。 …...

TypeScript 中高级类型 keyof 与 typeof的场景剖析。

文章目录 前言一、typeof:从值到类型的映射1. 核心概念2. 类型推导示例3. 常见用途 二、keyof:从类型到键的映射1. 核心概念2. 常见用途 三、typeof keyof:强强联合的实战场景1. 场景一:对象属性的安全访问2. 场景二:…...

Android LiveData 详解

一、LiveData 核心概念与特性 1.1 定义与基本功能 LiveData 是 Android Jetpack 架构组件中的一个可观察数据持有者类,其核心功能是实现数据与 UI 的响应式绑定。与传统观察者模式不同,LiveData 具有生命周期感知能力,能够自动根据观察者…...

为什么共现矩阵是高维稀疏的

为什么共现矩阵是高维稀疏的? 共现矩阵(Co-occurrence Matrix)的高维稀疏性是其固有特性,主要由以下原因导致: 1. 高维性的根本原因 词汇表大小决定维度: 共现矩阵的维度为 ( V \times V ),其…...

离散化算法的二分法应用

我们思考一个问题:其实这里的二分法回归本源也是基于下标映射的原理,只是实现是借助二分的形式。 在排序好的数组中对目标数值进行二分搜索,在 O(logn) 的时间复杂度内找到该数值是整体数据中的第几个。 具体的我们可以如下操作: …...

IntelliJ IDEA 中进行背景设置

🎨 ​​一、全局主题切换​​ ​​操作路径​​ File → Settings → Appearance & Behavior → Appearance → Theme​​可选主题​​: ​​Darcula​​:深色模式(默认暗黑主题)​​IntelliJ Light​​&#xff…...

Dart语言学习指南「专栏简介」

Dart 是 Google 开发的一款开源通用编程语言,它不仅支持客户端和服务器端的应用开发,还因其与 Flutter 框架的深度集成,在移动端和 Web 开发中广受欢迎。Dart 适用于 Android 应用、iOS 应用、物联网(IoT)项目以及 Web…...

AWS之AI服务

目录 一、AWS AI布局 ​​1. 底层基础设施与芯片​​ ​​2. AI训练框架与平台​​ ​​3. 大模型与应用层​​ ​​4. 超级计算与网络​​ ​​与竞品对比​​ AI服务 ​​1. 机器学习平台​​ ​​2. 预训练AI服务​​ ​​3. 边缘与物联网AI​​ ​​4. 数据与AI…...

Docker 部署项目

使用 Docker 部署项目是一个很好的选择,可以避免服务器环境不兼容的问题,并且能够实现一致性和可移植性。我会给你一个详细的步骤,帮你从零开始理解 Docker,最终在服务器上部署 Roop 项目。 1. 安装 Docker 首先,你需…...

半导体厂房设计建造流程、方案和技术要点-江苏泊苏系统集成有限公司

半导体厂房设计建造流程、方案和技术要点-江苏泊苏系统集成有限公司 半导体厂房的设计建造是一项高度复杂、专业性极强的系统工程,涉及洁净室、微振动控制、电磁屏蔽、特殊气体/化学品管理等关键技术。 一、设计建造流程: 1.需求定义与可行性分析 &a…...

(c++)string的模拟实现

目录 1.构造函数 2.析构函数 3.扩容 1.reserve(扩容不初始化) 2.resize(扩容加初始化) 4.push_back 5.append 6. 运算符重载 1.一个字符 2.一个字符串 7 []运算符重载 8.find 1.找一个字符 2.找一个字符串 9.insert 1.插入一个字符 2.插入一个字符串 9.erase 10…...

一种通用图片红色印章去除的工具设计

朋友今天下午需要处理个事情,问我有没有什么好的办法能够去除,核心问题是要去除图片上的印章。记得以前处理过类似的需求,photoshop操作比较简单,本质是做运算。这种处理方式有很多,比如现在流行的大模型,一…...

企业应用AI对向量数据库选型思考

一、向量数据库概述 向量数据库是一种专门用于存储和检索高维向量数据的数据库系统,它能够高效地处理基于向量相似性的查询,如最近邻搜索等,在人工智能、机器学习等领域的应用中发挥着重要作用,为处理复杂的向量数据提供了有力的…...

时序数据库IoTDB安装学习经验分享

1. JDK安装问题 在安装IoTDB时,我遇到了“无法加载主类”的错误,这通常表明Java环境存在问题。尽管我能正确输出classpath和查询JDK版本,但问题依旧存在。经过查阅相关资料,我发现问题出在多余的classpath设置上。Java编译器和虚…...

RapidOCR集成PP-OCRv5_det mobile模型记录

该文章主要摘取记录RapidOCR集成PP-OCRv5_mobile_det记录,涉及模型转换,模型精度测试等步骤。原文请前往官方博客: https://rapidai.github.io/RapidOCRDocs/main/blog/2025/05/26/rapidocr%E9%9B%86%E6%88%90pp-ocrv5_det%E6%A8%A1%E5%9E%8B…...

当 Redis 作为缓存使用时,如何保证缓存数据与数据库(或其他服务的数据源)之间的一致性?

当 Redis 作为缓存使用时,保证缓存数据与数据库(或其他数据源)之间的一致性是一个核心挑战。通常,我们追求的是“最终一致性”,而不是“强一致性”,因为强一致性往往会牺牲性能和可用性,这与使用…...

Dify理论+部署+实战

概述 一个功能强大的开源AI应用开发平台,融合后端即服务(Backend as Service)和LLMOps理念,使开发者能够快速搭建生产级的生成式AI应用。 核心优势 直观的用户界面:提供简洁明了的操作界面,使得用户能够…...

内网穿透系列五:自建SSH隧道实现内网穿透与端口转发,Docker快速部署

​以下是对这个自建SSH隧道工具的简单介绍: 一款基于OpenSSH构建的内网穿透与端口转发工具,通过SSH隧道技术实现支持所有TCP协议通信,包括SSH、HTTP、HTTPS等各类应用提供灵活部署方式,特别支持Docker容器化快速部署开源工具地址…...

桥梁进行3D建模时的数据采集、存储需求及技术参数

桥梁进行3D建模时的数据采集、存储需求及技术参数 1公里桥梁进行3D建模时的数据采集、存储需求及技术参数的详细分析 1. 照片数量估算 关键影响因素 桥梁类型:梁桥/拱桥/斜拉桥(结构复杂度不同) 建模精度:工程级(1-…...

Transformer架构技术学习笔记:从理论到实战的完整解析

引言:重新定义序列建模的里程碑 2017年,Vaswani等人在论文《Attention Is All You Need》中提出的Transformer架构,彻底改变了自然语言处理领域的游戏规则。与传统RNN/LSTM相比,Transformer具有三大革命性特征: 全注意…...

1、python代码实现与大模型的问答交互

一、基础知识 1.1导入库 torch 是一个深度学习框架,用于处理张量和神经网络。modelscope是由阿里巴巴达摩院推出的开源模型库。 AutoTokenizer 是ModelScope 库的类,分词器应用场景包括自然语言处理(NLP)中的文本分类、信息抽取…...

CPU服务器的主要功能有哪些?

服务器作为互联网社会中基础的网络设施,为企业提供了存储和传输文件的功能,而中央处理器作为服务器计算能力的核心部分,能够帮助企业进行十分复杂的科学计算任务,本文就主要来探索一下CPU服务器的主要功能都有哪些吧! …...

如何在 Vue.js 中集成 Three.js —— 创建一个旋转的 3D 立方体

在这篇文章中,我将向大家展示如何将 Three.js 与 Vue.js 结合,创建一个简单的 3D 场景,并展示一个旋转的立方体。通过这个简单的示例,你将学习到如何在 Vue 项目中集成 Three.js,以及如何创建动态的 3D 内容。 1. 安装…...

Java开发经验——阿里巴巴编码规范实践解析6

摘要 本文深入解析了阿里巴巴编码规范在数据库设计和Java开发中的实践应用。详细阐述了数据库字段命名、类型选择、索引命名等规范,以及Java POJO类的对应规范。强调了字段命名的重要性,如布尔字段命名规则、表名和字段名的命名禁忌等。同时&#xff0c…...

docker常见考点

一、基础概念类 Docker与虚拟机的区别 Docker基于容器化技术,共享宿主机内核,资源消耗更少;虚拟机通过Hypervisor虚拟化硬件,资源占用高。Docker启动速度更快(秒级),虚拟机需要启动完整操作系统…...

工业自动化实战:基于 VisionPro 与 C# 的机器视觉 PLC 集成方案

一、背景介绍 在智能制造领域,机器视觉检测与 PLC 控制的无缝集成是实现自动化生产线闭环控制的关键。本文将详细介绍如何使用 C# 开发上位机系统,实现 Cognex VisionPro 视觉系统与西门子 S7 PLC 的数据交互,打造高效、稳定的工业检测方案。…...