分析并实现Android中的MVC、MVP架构模式

架构是什么

架构是为了解决特定的问题而提出来的,而且它还有特定的规则,能够把整个应用的整体进行角色的划分。并且他还能够约定角色之间的联系沟通机制。

所以学习架构要带着以下三个问题去理解:

。架构解决了什么问题?

。架构模式是如何划分角色的?

。角色间是如何建立联系的?

在Android当中,经常被大家提及到就是MVC、MVP和MVVM。本文来分析一下MVC、MVP各自是怎么实现的,怎么写的,以及解决了什么问题而提出来的。

MVC

什么是MVC架构

MVC的话它本来不属于Android的架构模式,而是来自于web前端。在Android发展的前期照搬了前端这一套模式。

MVC模式就是Model、View和Controller。View的职责就是处理显示相关的逻辑以及接收用户行为。再把用户行为转发到Controller,Controller再根据请求去更新或者是获取Model层的数据。Controller更像是一个中转站或者是调度站。Model 负责管理数据、执行业务逻辑。MVC在前端的作用是为了分离数据和视图这两层,但是在Android上面它就不灵光了。

在Android语境下,这里的Controller一般特指Activity和Fragment。而Model可以是 Java 类、数据库、网络请求或其他数据源,就是负责数据的读取操作的。而View的话一般来说是指XML布局文件。

代码实例

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"xmlns:app="http://schemas.android.com/apk/res-auto"xmlns:tools="http://schemas.android.com/tools"android:layout_width="match_parent"android:layout_height="match_parent"tools:context=".mvc.MvcActivity"><Buttonandroid:id="@+id/bt_mvc_login"android:layout_width="wrap_content"android:layout_height="wrap_content"app:layout_constraintLeft_toLeftOf="parent"app:layout_constraintRight_toRightOf="parent"app:layout_constraintTop_toTopOf="parent"android:layout_marginTop="20dp"android:text="登录" /><TextViewandroid:id="@+id/tv_mvc_response"android:layout_width="wrap_content"android:layout_height="wrap_content"app:layout_constraintLeft_toLeftOf="parent"app:layout_constraintRight_toRightOf="parent"app:layout_constraintTop_toBottomOf="@+id/bt_mvc_login"android:layout_marginTop="20dp"android:padding="5dp"android:text="data:"/></androidx.constraintlayout.widget.ConstraintLayout>

model

public class LoginModel {private static final String TAG = "LoginModel";private static final String URL = "https://api.cdnjs.com/libraries/jquery/3.5.1";private OnLoginListener mListener;public interface OnLoginListener {void onSuccess(String data);void onFail();}public void login(OnLoginListener listener) {mListener = listener;OkHttpClient client = new OkHttpClient();Request request = new Request.Builder().url(URL).build();client.newCall(request).enqueue(new Callback() {@Overridepublic void onFailure(Call call, IOException e) {Log.d(TAG, "onFailure");if(null != mListener){mListener.onFail();}}@Overridepublic void onResponse(Call call, Response response) throws IOException {String message = response.body().string();Log.d(TAG, "onResponse:" + message);if(null != mListener){mListener.onSuccess(message);}}});}
}

control


public class MvcActivity extends AppCompatActivity {private static final String TAG = "MvcActivity";private LoginModel model;private Button button;private TextView textView;private Handler mHandler = new Handler();@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_mvc);button = findViewById(R.id.bt_mvc_login);textView = findViewById(R.id.tv_mvc_response);model = new LoginModel();button.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View view) {//请求数据model.login(new LoginModel.OnLoginListener() {@Overridepublic void onSuccess(String data) {//更新UIrunOnUiThread(new Runnable() {@Overridepublic void run() {updateView(data);}});}@Overridepublic void onFail() {}});}});}private void updateView(String data) {textView.setText(data);}
}

上面的代码简单实现了在点击登录按钮后获取数据显示到 TextView。

缺点

很明显,这种开发模式它的缺点就是当页面逻辑复杂时,容易导致Activity的代码膨胀。可能一个Activity当中它的代码量分分钟可以标到上千行。如果要修改某一处业务逻辑的话,有可能去找某个方法就要找半天,原因是Layout布局无法帮助Controller分担数据绑定的逻辑。

Activity虽然能够作为一个很称职的MVC Controller,但是作为一个类来说,它的职责太多了,需要实现的代码也太多了。首先从性能角度出发,Activity在使用期间会有大量的时间驻留在内存中,如果它的代码太多,就会导致性能问题。第二个也是最重要的,就是从分层架构的角度来说。如果某个层次过厚是不利于解耦的,我们就需要对这个层进行更细的拆分。

MVP

什么是MVP架构

后来为了解决Activity任务过于繁重,数据层与视图层交织在一起的问题,演化出来的MVP模式。它的主要特性就是让视图层和数据层分离。

Activity 和 Fragment 视为View层,负责处理 UI和用户交互;

Presenter 为业务处理层,负责处理业务逻辑和发起数据的请求;

Model 层中包含着具体的数据请求,数据源。

这三者之间的关系是View调用Presenter,然后再调用Model去完成数据的请求动作。Model通过callback把数据回传给Presenter,然后Presenter再通过他持有的View接口,把数据回传到View层更新UI。

代码实例

将上面的mvc改成mvp

public class MvpActivity extends AppCompatActivity implements LoginContract.View{private static final String TAG = "MvpActivity";private LoginPresenter loginPresenter;private Button button;private TextView textView;private Handler mHandler = new Handler();@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_mvc);button = findViewById(R.id.bt_mvc_login);textView = findViewById(R.id.tv_mvc_response);loginPresenter = new LoginPresenter();loginPresenter.attach(this);button.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View view) {loginPresenter.getUserInfo();}});}@Overridepublic void onResult(String data) {Log.d(TAG, "onResult data:" + data);runOnUiThread(new Runnable() {@Overridepublic void run() {textView.setText(data);}});}@Overrideprotected void onDestroy() {super.onDestroy();//释放loginPresenter.detach();}
}

presenter

public interface BaseView {
}public class BasePresenter<IView extends BaseView> {protected IView view;/*** 绑定view* @param view*/public void attach(IView view) {this.view = view;}public void detach() {view = null;}
}public interface LoginContract {interface View extends BaseView {void onResult(String data);}//定义的每个方法都会在view结构当中存在与之相对应的回调方法abstract class Presenter extends BasePresenter<View> {abstract void getUserInfo();}}public class LoginPresenter extends LoginContract.Presenter {private static final String TAG = "LoginPresenter";@Overridevoid getUserInfo() {LoginModel model = new LoginModel();model.login(new LoginModel.OnLoginListener() {@Overridepublic void onSuccess(String data) {view.onResult(data);}@Overridepublic void onFail() {}});}
}

model

缺点

MVP这种开发模式对于简单的应用程序可能会显得过于复杂,MVP需要开发额外的Presenter类,可能增加开发工作量。为了实现MVP,通常需要定义大量的接口,这可能增加代码的复杂性。

总结

虽然MVP是MVC的优化后的产物,但还是各有利弊的。MVP解决了MVC在复杂项目中导致的Activity代码膨胀和维护难的问题。MVP复用代码的难度更低,实现方式替换起来更灵活。但是MVC的好处就是能够快速开发,在简单的页面上面使用起来非常的容易上手。所以我们到底要选择哪一种开发模式,需要看具体的场景。

Android 学习笔录

Android 性能优化篇:https://qr18.cn/FVlo89
Android Framework底层原理篇:https://qr18.cn/AQpN4J
Android 车载篇:https://qr18.cn/F05ZCM
Android 逆向安全学习笔记:https://qr18.cn/CQ5TcL
Android 音视频篇:https://qr18.cn/Ei3VPD
Jetpack全家桶篇(内含Compose):https://qr18.cn/A0gajp
OkHttp 源码解析笔记:https://qr18.cn/Cw0pBD
Kotlin 篇:https://qr18.cn/CdjtAF
Gradle 篇:https://qr18.cn/DzrmMB
Flutter 篇:https://qr18.cn/DIvKma
Android 八大知识体:https://qr18.cn/CyxarU
Android 核心笔记:https://qr21.cn/CaZQLo
Android 往年面试题锦:https://qr18.cn/CKV8OZ
2023年最新Android 面试题集:https://qr18.cn/CgxrRy
Android 车载开发岗位面试习题:https://qr18.cn/FTlyCJ
音视频面试题锦:https://qr18.cn/AcV6Ap

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/112051.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

AUTOSAR AP硬核知识点梳理(1)

一 什么是 Adaptive AUTOSAR? Adaptive AUTOSAR是一种新的汽车软件框架,旨在满足现代汽车行业中不断增长的技术需求。随着汽车变得越来越智能,对处理器的性能要求也在不断增长。 Adaptive AUTOSAR旨在通过提供高性能计算和通信机制以及灵活的软件配置来满足这些需求,为车…

软考 系统架构设计师系列知识点之基于架构的软件开发方法ABSD(8)

接前一篇文章&#xff1a;软考 系统架构设计师系列知识点之基于架构的软件开发方法ABSD&#xff08;7&#xff09; 所属章节&#xff1a; 第7章. 系统架构设计基础知识 第5节. 特定领域软件体系结构 相关试题 5. ABSDM&#xff08;Architecture-Based Software Design Mode&a…

金某OA协同办公管理系统存在任意文件下载漏洞复现 CNVD-2021-43036

目录 1.漏洞概述 2.影响版本 3.漏洞等级 4.漏洞复现 5.Nuclei自动化验证 4.修复建议

软件工程与计算总结(二十)软件交付

软件交付是软件项目的结束阶段 &#xff0c;标志着软件开发任务的完成——其作为一个分水岭&#xff0c;区分了软件开发与软件维护两个既连续又不同的软件产品生存状态~ 在经历连续的辛苦工作之后&#xff0c;开发人员在胜利曙光之前难免会忽视软件交付阶段的一些工作——在准…

踩坑记 BSS段的初始化

title: 踩坑记 BSS段的初始化 category_bar: true categories: blog tags:embedded date: 2023-10-20 19:23:05 前言 接手一个项目&#xff0c;调试全靠串口日志&#xff0c;测试同事测试产品的时候无法拿到日志&#xff0c;刚好产品RAM够大&#xff0c;且刚好有SD卡。所以就…

Arcgis中像元值变化问题,拉伸显示的是否为实际像元值范围?

Arcgis中合并栅格但像元值变化 问题描述 这是四幅栅格&#xff0c;范围都在-1-9之间&#xff0c;怀疑这个范围是否是真实的范围。因为经常听到同学说放到arcgis拉伸显示之后&#xff0c;值变化了&#xff0c;所以研究一下。 原因 可以打开ENVI的像元快速统计工具&#xff…

SeaTunnel 换maven源,解决插件下载慢

SeaTunnel 是使用的mvnw命令,可以先执行一下install-plugin.sh然后终止 理论上应该可以直接执行mvnw,他就会去安装下载maven,目录就是下面的目录 然后去服务器目录修改 setting.xml文件,设置镜像源即可 /root/.m2/wrapper/dists/apache-maven-3.8.4-bin/52ccbt68d252mdldqsfsn…

2023 年 的 DBA 有哪些变化?

作者&#xff1a;Craig S. Mullins 数据库专家&#xff0c;IBM 优化冠军&#xff0c;DB2 金牌顾问以及 IDUG 名人堂成员&#xff0c;数据库类畅销书作者&#xff0c;著有《DB2 Developers Guide》、《Database Administration: The Complete Guide to DBA Practices & Pro…

基于GRU的 电影评论情感分析 - python 深度学习 情感分类 计算机竞赛

文章目录 1 前言1.1 项目介绍 2 情感分类介绍3 数据集4 实现4.1 数据预处理4.2 构建网络4.3 训练模型4.4 模型评估4.5 模型预测 5 最后 1 前言 &#x1f525; 优质竞赛项目系列&#xff0c;今天要分享的是 基于GRU的 电影评论情感分析 该项目较为新颖&#xff0c;适合作为竞…

笔记1 Compute Shaders

Wending 2022/10/29 15:43:54 Compute Shaders是在GPU运行却又在普通渲染管线之外的程序&#xff0c;通过Compute Shader我们可以将大量可以并行的计算放到GPU中计算从而节省CPU资源 Wending 2022/10/29 15:44:27 反正不是传统的shader 不常用 博毅创为Blake老师 2022/10/29 15…

CKA场景题

CKA 权限控制 需求&#xff1a; 创建名称 deployment-clusterrole 的 ClusterRole&#xff0c;该⻆⾊具备创建 Deployment、Statefulset、 Daemonset 的权限&#xff0c;在命名空间 app-team1 中创建名称为 cicd-token 的 ServiceAccount&#xff0c;绑定 ClusterRole 到 Ser…

大托,如何站上天心南部的价值高地?

作者 | 魏启扬 陈宇航 来源 | 洞见新研社 陈飞 摄 “商贾云集于四方&#xff0c;市井数盈于万户”&#xff0c;长沙南城古往今来生生不息的热辣与烟火&#xff0c;每隔一段时间&#xff0c;都会有璀璨的迸发。 才在“加长版”黄金周释放了“不夜南城”的魅力&#xff0c;第…

【Python学习笔记】字符串格式化

1. printf 风格 这种格式化语法 和 传统的C语言printf函数 一样 。 salary input(请输入薪资&#xff1a;)# 计算出缴税额&#xff0c;存入变量tax tax int(salary) *25/100 # 计算出税后工资&#xff0c;存入变量aftertax aftertax int(salary) *75/100 print(税前薪资&…

2023年浙大MEM考前80天上岸经验分享

时间过得真快&#xff0c;转眼间已经是十月份了。回想起去年这个时候&#xff0c;我还在为考研而感到焦虑不安。然而&#xff0c;如今我已经在浙大MEM项目学习了一个多月的时间了。在这一个月的学习过程中&#xff0c;我不仅学到了许多专业知识&#xff0c;还结识了很多志同道合…

小白学java--垃圾回收机制(Garbage Collection)

压测过程中&#xff0c;作为测试会时不时听到研发说命中gc了&#xff0c;如果一头雾水&#xff0c;来看看什么是gc。 1、什么是垃圾回收机制 垃圾回收的执行过程会导致一些额外的开销&#xff0c;例如扫描和标记对象、回收内存空间等操作。这些开销可能会导致一定的性能损失和…

QT计时器

widget.h #ifndef WIDGET_H #define WIDGET_H#include <QWidget> #include <QTimerEvent> //计时器类 #include <QTime> //时间类 QT_BEGIN_NAMESPACE namespace Ui { class Widget; } QT_END_NAMESPACEclass Widget : public QWidget {Q_OBJECTpublic:Widg…

10.20作业

#include “widget.h” #include “ui_widget.h” Widget::Widget(QWidget *parent) QWidget(parent) , ui(new Ui::Widget) { ui->setupUi(this); t new QTimer(this); connect(t, &QTimer::timeout, this, &Widget::timeout_Slot); ui->text->setPlacehold…

microcom串口调试工具使用

microcom串口助手使用介绍 microcom是一个在终端中使用的串口助手&#xff0c;类似平常使用SSCOM一样的东西&#xff0c;不过是在终端中使用而已。 使用的是busybox构建的文件系统 microcom源码路径&#xff1a;busybox/miscutils/microcom.c microcom 参数&#xff1a; [r…

什么是响应式设计?响应式设计的基本原理是什么?如何兼容低版本的 IE?

什么是响应式设计: 响应式设计&#xff08;Responsive Design&#xff09;是一种Web设计和开发方法&#xff0c;旨在使网站在不同设备和屏幕尺寸上都能提供一致的用户体验。响应式设计的目标是适应多种终端&#xff0c;包括桌面计算机、笔记本电脑、平板电脑和移动设备&#x…

编程题总结 --- 2018

&#xff08;1&#xff09;输入一串字符串&#xff0c;字符串以“#”结尾&#xff0c;判断输入的字符串中0至9的个数。 #include<iostream>using namespace std;int main(){int sum 0;string s;while(cin >> s){if(s "#") break;int n s.size();for(…