【Android】浅析MVC与MVP
【Android】浅析MVC与MVP
什么是架构?
架构(Architecture)在软件开发中指的是软件系统的整体设计和结构,它描述了系统的高层组织方式,包括系统中各个组件之间的关系、依赖、交互方式,以及这些组件如何协同工作来完成系统的功能。
架构不仅仅是指代码的结构,它还涵盖了系统的各个方面,包括:
- 组件的划分:将系统拆分成模块、类、服务等单元。
- 组件间的交互:不同模块、组件如何传递信息、调用服务等。
- 数据流:数据如何在系统中流动,从输入到输出的路径是什么。
- 非功能性需求:如何考虑系统的性能、可扩展性、安全性、可维护性等。
架构模式,其实更多的是一种思想,一种规则,往往一种架构模式可能会有不同的实现方式,而实现方式之间,只有合适与否,并没有对错之分。
- 为了解决特定的问题而提出
- 按照特定的原则将系统整体进行模块/组件/角色的划分
- 建立模块/组件/角色间的沟通机制
摘自:https://zhuanlan.zhihu.com/p/83635530
MVC架构
在不同的框架或平台上,MVC(Model-View-Controller)架构的具体实现方式会有所不同,但其核心思想是不变的:将数据、逻辑与用户界面分离,以提高应用程序的可维护性、可扩展性和灵活性。
Model-View-Controller
MVC 将应用程序分为三个主要的部分:
Model
Model 负责应用程序的业务逻辑和数据处理,它代表了应用中的数据和状态。所有与数据相关的操作(如网络请求、数据库操作等)都在Model中进行。
职责:管理应用的数据,包括获取数据、存储数据、处理数据、数据验证等。
在Android中的体现:
- 可以是任何与数据处理相关的类,比如网络请求类、数据库操作类等。
- 例如:通过Room数据库、SQLite数据库、或者API接口获取数据。
View
View 负责显示数据,是应用程序用户界面(UI)的表现部分。View直接与用户交互,展示Model中的数据并将用户操作传递给Controller进行处理。
职责:展示Model中的数据,并响应用户的交互操作(如点击按钮、输入文本等)。
在Android中的体现:
- XML布局文件(Layout)或Java中的UI元素(如
TextView
、Button
等)。 - Fragment或Activity中的
onCreate()
方法中设置布局和更新UI的代码。 - View本身不应该包含业务逻辑,只负责显示数据和响应事件。
Controller
Controller 负责协调Model和View之间的交互,通常处理用户输入并将这些输入传递给Model,之后将Model处理的数据结果反馈给View。
职责:接收用户操作的输入,调用Model更新数据,并通知View来更新UI。
在Android中的体现:
- Activity和Fragment通常充当Controller的角色,因为它们负责管理UI逻辑和用户交互。
- 在Activity或Fragment中,通过监听用户的交互事件(如点击事件)来修改Model,然后更新View。
解决什么问题
如果不使用架构进行开发,会导致 Activity / Fragment 逻辑臃肿,不利于扩展。
所以 MVC 就要解决的问题就是:控制逻辑,数据处理逻辑和界面交互耦合。
数据的流向
MVC 模式的工作流程
- 用户操作 View:用户通过UI进行某些操作(如点击按钮、输入文本等),这些操作通过事件监听传递到Controller。
- Controller 更新 Model:Controller接收用户的操作,并根据操作调用Model来获取或更新数据(比如向API发送请求,或者从数据库中获取数据)。
- Model 变更通知:Model处理完数据后,将更新后的数据通知给Controller或直接通知View。
- View 更新显示:Controller根据Model的数据变化来更新View,从而将新数据展示给用户。
在传统的 MVC 模式中,View 和 Model 可以直接通信。也就是说,View
可以直接读取 Model
的数据,而不需要通过 Controller
。这种直接通信导致 View
和 Model
之间的耦合度较高,尤其在复杂应用中,难以维护和测试。
MVC 架构模式的优缺点
优点:
- 结构清晰,职责划分清晰
- 降低耦合
- 有利于组件重用
缺点:
- 其实我们上述的示例,已经是经过优化的 MVC 结构了,Activity / Fragment 会承担 View 和 Controller 两个角色,就会导致 Activity / Fragment 中代码较多
- Model 直接操作 View,View 的修改会导致 Controller 和 Model 都进行改动
- 增加了代码结构的复杂性
虽然MVC是一个经典的设计模式,但在Android开发中,由于Activity和Fragment承担了太多的角色(既作为Controller,又直接操作View),会导致代码臃肿,维护困难。因此,Android开发中更多地使用MVP(Model-View-Presenter)或MVVM(Model-View-ViewModel)架构模式,来更好地解耦UI和业务逻辑。
MVP
MVP(Model-View-Presenter)是Android开发中的一种架构模式,旨在通过更清晰地分离职责,解决MVC中Activity和Fragment过度承担的角色,使代码更加模块化、可维护性更高。MVP将逻辑代码与UI代码解耦,避免了UI组件直接与业务逻辑耦合。MVP是对MVC模式的改进,非常适合中小型Android应用。
Model-View-Presenter
- Model(模型) Model在MVP中负责数据的处理和业务逻辑,跟MVC中的Model角色一致。它与Presenter通信,提供数据和执行相应的业务逻辑。
- View(视图) View负责展示UI,与用户进行交互。它只处理用户输入和UI更新,不包含业务逻辑。在MVP中,View通过接口与Presenter通信,将事件交由Presenter处理,而不是自己操作业务逻辑。
- Presenter(控制器) Presenter是MVP的核心,它作为Model和View之间的中介,负责从Model获取数据并通知View进行更新。Presenter中不应该包含任何UI代码,它只处理逻辑和决定如何将数据传递给View。
解决什么问题
MVP 要解决的问题和 MVC 大同小异:控制逻辑,数据处理逻辑和界面交互耦合,同时能将 MVC 中的 View 和 Model 解耦。
数据流向
MVC 和 MVP 的核心区别:角色通信
MVC 中,View
和 Model
直接交互。这意味着 View
可能直接访问 Model
来获取数据,也可以监听 Model
的变化并更新界面。Controller
作为用户输入的处理者,接收用户输入并将其转发给 Model
或 View
。这种直接交互可能导致View
和Model
之间的耦合度较高。
MVP 则通过 Presenter 作为中介,解耦了 View 和 Model 之间的直接通信。View
不会直接访问 Model
,所有的数据交互、逻辑处理、UI 更新都通过 Presenter
进行。View
只负责呈现数据,而不涉及任何业务逻辑。Presenter
负责处理业务逻辑,并且通过接口与View
和Model
交互,从而实现低耦合。
MVP 中的数据流向
MVP 模式下的数据流向可以总结为以下几个步骤:
用户事件触发(View -> Presenter):
用户在 UI 界面(
View
)上执行操作(如点击按钮、输入文本等)。View
接收到用户的交互后,不直接处理逻辑,而是将事件传递给Presenter
。业务逻辑处理(Presenter -> Model):
Presenter
负责处理用户的输入,并做出相应的业务逻辑处理。如果需要修改数据或与后端进行交互,Presenter
会通过接口调用Model
的方法,来处理业务逻辑或更新数据。数据更新(Model -> Presenter):
Model
根据Presenter
的指令更新数据或获取数据。当Model
处理完数据之后,它会将结果返回给Presenter
。界面更新(Presenter -> View):
Presenter
收到来自Model
的新数据后,将这些数据传递给View
,从而驱动 UI 界面的更新。View
只负责根据Presenter
提供的数据更新界面,不会进行数据处理或逻辑处理。
举个栗子吧~:
以一个简单的登录流程为例:
用户输入用户名和密码,点击登录按钮:
用户在 View
中(例如 LoginActivity
)输入用户名和密码,并点击“登录”按钮。View
不直接处理输入,而是将事件通知给 Presenter
。例如:presenter.onLoginButtonClick(username, password)
。
Presenter 接收用户输入,开始验证逻辑:
Presenter
接收到用户输入后,执行登录验证逻辑。Presenter
通过调用 Model
的方法(例如 model.login(username, password)
)来进行登录操作。
Model 处理登录逻辑:
Model
负责处理登录的具体业务逻辑,例如查询数据库或通过网络请求验证用户名和密码。验证成功后,Model
将结果返回给 Presenter
(例如成功或失败的状态)。
Presenter 获取验证结果,并通知 View 更新界面:
Presenter
接收到登录的结果后,决定如何通知 View
更新界面。如果登录成功,Presenter
可能调用 View
的方法来显示“登录成功”的消息;如果失败,则显示“登录失败”的提示。
MVP 架构模式的优缺点
优点:
- 结构清晰,职责划分清晰
- 模块间充分解耦
- 有利于组件的重用
缺点:
- 会引入大量的接口,导致项目文件数量激增
- 增大代码结构复杂性
结语
本文仅仅对MVP和MVC做了一个小的总结,希望在日后可以学习更多有关架构模式的知识,例如:依赖注入、响应式编程、MVVM等。
参考:
Android 开发中的架构模式 – MVC / MVP / MVVM - 知乎 (zhihu.com)
相关文章:

【Android】浅析MVC与MVP
【Android】浅析MVC与MVP 什么是架构? 架构(Architecture)在软件开发中指的是软件系统的整体设计和结构,它描述了系统的高层组织方式,包括系统中各个组件之间的关系、依赖、交互方式,以及这些组件如何协同…...
spark 面试题
spark 面试题 1、spark 任务如何解决第三方依赖 比如机器学习的包,需要在本地安装?--py-files 添加 py、zip、egg 文件不需要在各个节点安装 2、spark 数据倾斜怎么解决 spark 中数据倾斜指的是 shuffle 过程中出现的数据倾斜,主要是由于…...

青柠视频云——如何开启HTTPS服务?
前言 由于青柠视频云的语音对讲会使用到HTTPS服务,这里我们说一下如何申请证书以及如何在实战中部署并且配置使用。 一、证书申请 1、进入控制台 我们拿阿里云的免费个人证书为例,首先登录阿里云,在控制台找到数字证书管理服务,进…...

2016年国赛高教杯数学建模A题系泊系统的设计解题全过程文档及程序
2016年国赛高教杯数学建模 A题 系泊系统的设计 近浅海观测网的传输节点由浮标系统、系泊系统和水声通讯系统组成(如图1所示)。某型传输节点的浮标系统可简化为底面直径2m、高2m的圆柱体,浮标的质量为1000kg。系泊系统由钢管、钢桶、重物球、…...

vue-使用refs取值,打印出来是个数组??
背景: 经常使用$refs去获取组件实例,一般都是拿到实例对象,这次去取值的时候发现,拿到的竟然是个数组。 原因: 这是vue的特性,自动把v-for里面的ref展开成数组的形式,哪怕你的ref名字是唯一的!…...

微服务_入门1
文章目录 一、 认识微服务二、 微服务演变2.1、 单体架构2.2、 分布式架构2.3、 微服务2.4、 微服务方案对比 三、 注册中心3.1、 Eureka3.2、 Nacos3.2.1、服务分级存储模型3.2.2、权重配置3.2.3、环境隔离 一、 认识微服务 二、 微服务演变 随着互联网行业的发展,…...

【学习资料】袋中共36个球,红白黑格12个,问能一次抽到3个红4个白5个黑的概率是多少?
1、公式计算 1.1 题目1 袋中共 36 36 36个球, 红 \fcolorbox{red}{#FADADE}{\color{red}{红}} 红 白 \fcolorbox{white}{#808080}{\color{white}{白}} 白 黑 \fcolorbox{#808080}{#0D0D0D}{\color{#808080}{黑}} 黑各 12 12 12个,问能一次抽到 3…...
@PathVariable,@RequestParam,@RequestBody注解,springboot与前端请求之间的数据类型转换
前端数据与springboot java数据类型转换 springboot&mybatis中数组和字符串数据类型的转换-CSDN博客中曾经提到,在Spring Boot中,通过URL传参、payload中的key-value形式或json形式,将前端数据以字符串格式发送到后端,后端We…...
在Python中优雅地打开和操作RDS
在Python中优雅地打开和操作RDS 随着数据存储需求的不断增长,关系数据库服务(Relational Database Service, RDS)成为了许多企业首选的数据存储方式。那么,在Python中如何轻松地与RDS进行交互呢?以下是一份详尽的指南…...

.whl文件下载及pip安装
以安装torch_sparse库为例 一、找到自己需要的版本,点击下载。 去GitHub的pyg-team主页中找到pytorch-geometric包。网址如下: pyg-team/pytorch_geometricgithub.com/pyg-team/pytorch_geometric 然后点击如图中Additional Libraries位置的here&am…...

望繁信科技受邀出席ACS2023,为汽车行业数智化护航添翼
2023年5月25-26日,ACS2023第七届中国汽车数字科技峰会在上海成功举行。此次峰会汇聚了众多汽车领域的顶级专家、产业链代表及企业高管,共同探讨当今汽车产业的转型与未来发展趋势。 作为唯一受邀的流程挖掘厂商代表,望繁信科技携最新行业优势…...

基于 C语言的 Modbus RTU CRC 校验程序
一、CRC校验原理 Modbus RTU是一种常用于工业设备通信的协议,它基于串行通信,如RS-232或RS-485。在Modbus RTU中,CRC(循环冗余校验)是一种常用的错误检测机制,用于确保数据在传输过程中的完整性和准确性。 …...

基于微信小程序的剧本杀游玩一体化平台
作者:计算机学姐 开发技术:SpringBoot、SSM、Vue、MySQL、JSP、ElementUI、Python、小程序等,“文末源码”。 专栏推荐:前后端分离项目源码、SpringBoot项目源码、SSM项目源码 系统展示 基于微信小程序JavaSpringBootVueMySQL的剧…...
AMD或Intel上编译出来的程序,可以跑在海光上吗?
在上一篇博文《海光处理器与AMD Zen1的指令差异-CSDN博客》中发现,海光相比AMD,缺失了一些指令集。 那么在AMD或Intel上编译出来的程序,可以跑在海光上吗? 这个问题的关键,在于编译器默认使用哪些指令来编译程序。以Ce…...

ChatGPT 4o 使用指南 (9月更新)
首先基础知识还是要介绍得~ 一、模型知识: GPT-4o:最新的版本模型,支持视觉等多模态,OpenAI 文档中已经更新了 GPT-4o 的介绍:128k 上下文,训练截止 2023 年 10 月(作为对比,GPT-4…...

微信getUserProfile不弹出授权框
当我们在微信小程序开发工具中想要使用getUserProfile来获取个人信息的时候,会发现不弹出授权框,这是什么原因呢? 早在2022年的小程序官方公告中就已经明确给出了小程序用户头像昵称获取规则调整公告 因此如果还想继续使用getUserProfile的弹…...
iostat 命令:系统状态监控
一、命令简介 iostat 命令用于报告系统中 CPU、磁盘、tty 设备和 CPU 利用率统计信息。 需安装 sysstat 软件包,该软件包提供了一组工具,包括 iostat、sar、mpstat 等,用于系统性能监控和报告。 二、命令参数 iostat…...
从底层原理上解释 ClickHouse 的索引
ClickHouse 是一款高性能的列式数据库,它通过列式存储、稀疏索引、MergeTree 引擎等技术实现了极高的查询效率和吞吐量。索引是数据库中提高查询效率的关键机制之一。为了深入了解 ClickHouse 中的索引实现机制,我们将从底层原理、关键数据结构以及 Clic…...
9.20-使用k8s部署wordpress项目
部署wordpress项目 部署mariadb # 启动docker进程systemctl start docker# 拉取三个镜像docker pull nginx:alpinedocker pull wordpress:latestdocker pull mariadb:latest# 保存三个镜像cddocker save -o wordpress.tar wordpress:latestdocker save -o mariadb.tar…...

OSPFv3协议几类LSA介绍
OSPFv3协议介绍 与OSPFv2相比,OSPFv3在工作机制上与OSPFv2基本相同;但为了支持IPv6地址格式,OSPFv3对OSPFv2做了一些改动。OSPFv3基于OSPFv2基本原理增强,是一个独立的路由协议(v3不兼容v2)协议号仍然是89…...
[特殊字符] 智能合约中的数据是如何在区块链中保持一致的?
🧠 智能合约中的数据是如何在区块链中保持一致的? 为什么所有区块链节点都能得出相同结果?合约调用这么复杂,状态真能保持一致吗?本篇带你从底层视角理解“状态一致性”的真相。 一、智能合约的数据存储在哪里…...

突破不可导策略的训练难题:零阶优化与强化学习的深度嵌合
强化学习(Reinforcement Learning, RL)是工业领域智能控制的重要方法。它的基本原理是将最优控制问题建模为马尔可夫决策过程,然后使用强化学习的Actor-Critic机制(中文译作“知行互动”机制),逐步迭代求解…...
Spring Boot面试题精选汇总
🤟致敬读者 🟩感谢阅读🟦笑口常开🟪生日快乐⬛早点睡觉 📘博主相关 🟧博主信息🟨博客首页🟫专栏推荐🟥活动信息 文章目录 Spring Boot面试题精选汇总⚙️ **一、核心概…...

Module Federation 和 Native Federation 的比较
前言 Module Federation 是 Webpack 5 引入的微前端架构方案,允许不同独立构建的应用在运行时动态共享模块。 Native Federation 是 Angular 官方基于 Module Federation 理念实现的专为 Angular 优化的微前端方案。 概念解析 Module Federation (模块联邦) Modul…...
【C语言练习】080. 使用C语言实现简单的数据库操作
080. 使用C语言实现简单的数据库操作 080. 使用C语言实现简单的数据库操作使用原生APIODBC接口第三方库ORM框架文件模拟1. 安装SQLite2. 示例代码:使用SQLite创建数据库、表和插入数据3. 编译和运行4. 示例运行输出:5. 注意事项6. 总结080. 使用C语言实现简单的数据库操作 在…...

全志A40i android7.1 调试信息打印串口由uart0改为uart3
一,概述 1. 目的 将调试信息打印串口由uart0改为uart3。 2. 版本信息 Uboot版本:2014.07; Kernel版本:Linux-3.10; 二,Uboot 1. sys_config.fex改动 使能uart3(TX:PH00 RX:PH01),并让boo…...
C++八股 —— 单例模式
文章目录 1. 基本概念2. 设计要点3. 实现方式4. 详解懒汉模式 1. 基本概念 线程安全(Thread Safety) 线程安全是指在多线程环境下,某个函数、类或代码片段能够被多个线程同时调用时,仍能保证数据的一致性和逻辑的正确性…...

算法岗面试经验分享-大模型篇
文章目录 A 基础语言模型A.1 TransformerA.2 Bert B 大语言模型结构B.1 GPTB.2 LLamaB.3 ChatGLMB.4 Qwen C 大语言模型微调C.1 Fine-tuningC.2 Adapter-tuningC.3 Prefix-tuningC.4 P-tuningC.5 LoRA A 基础语言模型 A.1 Transformer (1)资源 论文&a…...

GruntJS-前端自动化任务运行器从入门到实战
Grunt 完全指南:从入门到实战 一、Grunt 是什么? Grunt是一个基于 Node.js 的前端自动化任务运行器,主要用于自动化执行项目开发中重复性高的任务,例如文件压缩、代码编译、语法检查、单元测试、文件合并等。通过配置简洁的任务…...
LangChain知识库管理后端接口:数据库操作详解—— 构建本地知识库系统的基础《二》
这段 Python 代码是一个完整的 知识库数据库操作模块,用于对本地知识库系统中的知识库进行增删改查(CRUD)操作。它基于 SQLAlchemy ORM 框架 和一个自定义的装饰器 with_session 实现数据库会话管理。 📘 一、整体功能概述 该模块…...