分析并实现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.rhkb.cn/news/164684.html

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

相关文章

Pytorch深度学习 - 学习笔记

文章目录 Pytorch深度学习1. Pytorch加载数据初认识2. TensorBoard3. Transforms常见的transform 4. torchvision中的数据集使用5. DataLoader使用6. 神经网络6.1 神经网络的基本骨架6.2 卷积层6.3 最大池化的使用6.4 非线性激活6.5 线性层及其他层6.6 小实战及Sequential 7. 损…

Python学习笔记——存储容器

食用说明&#xff1a;本笔记适用于有一定编程基础的伙伴们。希望有助于各位&#xff01; 列表 列表类似数组&#xff0c;其中可以包含不同类型的元素&#xff0c;写法如下&#xff1a; list1 [Google, Runoob, 1997, 2000] list2 [1, 2, 3, 4, 5 ] list3 ["a", …

antd的RangePicker设置默认值,默认近七天(andt+react)

import moment from "moment";state {initData:[moment().startOf(day).subtract(6, d), moment().endOf(day)], }<FormItem label"产生时间" {...tailItemLayout}>{getFieldDecorator("produceTime", {initialValue: initData})(<Ran…

VR航天科普主题公园模拟太空舱体验馆vr航天模拟体验设备

VR航天航空体验馆巡展是一项非常受欢迎的展览活动&#xff0c;可以让公众在现场体验到航天飞行的乐趣。 普乐蛙VR展览组织者会设计一个航天航空主题的VR体验馆&#xff0c;并在馆内设置各种航天航空相关的展示内容&#xff0c;如太空舱、火箭发射、星际航行等。 其次&#xff0…

信息检索与数据挖掘|(四)索引构建

目录 &#x1f4da;硬件基础 &#x1f4da;基于块的排序索引方法 &#x1f407;BSBI算法(blocked sort-based indexing) &#x1f4da;内存式单遍扫描索引构建方法 &#x1f407;SPIMI算法(single-pass in-memory indexing) &#x1f4da;分布式索引构建方法 &#x1f4d…

linux常见命令-时间日期类、搜索查找类、压缩和解压类

一、时间日期类 1.date 指令-显示当前日期 基本语法 1) date (功能描述:显示当前时间) 2) date %Y (功能描述:显示当前年份) 3) date %m (功能描述:显示当前月份) 4) date %d (功能描述:显示当前是哪一天) 5) date "%Y-%m-%d %H:%M:%S" (功能描述:显示年月…

《java 桌面软件开发》swing 以鼠标为中心放大缩小移动图片

swing 使用Graphic2D 绘制图片&#xff0c;要实现对图片进行缩放和自由拖动。 1.以鼠标所在的位置为中心&#xff0c;滚轮控制缩放 2.缩放后再支持鼠标拖动。 基本原理&#xff1a; 利用scale() 函数。进行缩放。但是要注意的地方是&#xff0c;如果是在 public void paintCom…

Flutter——最详细(CustomScrollView)使用教程

CustomScrollView简介 创建一个 [ScrollView]&#xff0c;该视图使用薄片创建自定义滚动效果。 [SliverList]&#xff0c;这是一个显示线性子项列表的银子列表。 [SliverFixedExtentList]&#xff0c;这是一种更高效的薄片&#xff0c;它显示沿滚动轴具有相同范围的子级的线性列…

【持续更新】tutorial-Linux-Markdown-etc(Linux、命令、Markdown、md、Tex、LaTex)

1. Linux命令 1.1 常用 查看文件夹下文件数量: ls -l | wc -l7zip: 解压&#xff1a;7z x compressed_file.7z -o/path/to/destination # 注意-o和目标路径是连起来的&#xff0c;没有空格压缩&#xff1a;7z a compressed_file.zip destination_path conda 查看 conda 拥有的…

Cornerstone for Mac:高效SVN管理的黄金标准

在当今的软件开发领域&#xff0c;版本控制系统是不可或缺的一部分。其中&#xff0c;Subversion&#xff08;SVN&#xff09;是一个广泛使用的版本控制系统&#xff0c;有助于团队协同工作&#xff0c;实现代码的版本管理和追踪。对于Mac用户来说&#xff0c;Cornerstone是一款…

服务器数据恢复-linux+raid+VMwave ESX数据恢复案例

服务器数据恢复环境&#xff1a; 一台某品牌x3950 X6型号服务器&#xff0c;linux操作系统&#xff0c;12块硬盘组建了一组raid阵列&#xff0c;上层运行VMwave ESX虚拟化平台。 服务器故障&#xff1a; 在服务器运行过程中&#xff0c;该raid阵列中有硬盘掉线&#xff0c;linu…

【cmake】cmake生成Visual Studio工程后的INSTALL项目使用

很多开源项目使用CMake生成Visual Studio工程后会有INSTALL项目。 这个INSTALL项目是为安装编译产物&#xff0c;作用类似于make install。其使用与其他工程并不相同。 想安装编译产物&#xff0c;需右键INSTALL工程&#xff0c;在弹出的菜单中&#xff0c;选择“仅用于项目”…

一百九十、Hive——Hive刷新分区MSCK REPAIR TABLE

一、目的 在用Flume采集Kafka中的数据直接写入Hive的ODS层静态分区表后&#xff0c;需要刷新表&#xff0c;才能导入分区和数据。原因很简单&#xff0c;就是Hive表缺乏分区的元数据 二、实施步骤 &#xff08;一&#xff09;问题——在Flume采集Kafka中的数据写入HDFS后&am…

记一次EDU证书站

如果文章对你有帮助&#xff0c;欢迎关注、点赞、收藏一键三连支持以下哦&#xff01; 想要一起交流学习的小伙伴可以加zkaq222&#xff08;备注CSDN&#xff0c;不备注通不过哦&#xff09;进入学习&#xff0c;共同学习进步 目录 目录 1.前言&#xff1a; 2.信息搜集 3.漏…

Python 文件打包成可执行文件

打包 要将Python脚本打包成可执行文件&#xff0c;常见的做法是使用PyInstaller或cx_Freeze工具。下面是使用PyInstaller的基本步骤&#xff1a; 使用conda安装pyinstaller &#xff08;建议&#xff09; conda install -c conda-forge pyinstaller上面的命令从conda-forge通…

二维码智慧门牌管理系统:革新小区安全管理的新力量

文章目录 前言一、外采人员的数据采集二、二维码智慧门牌管理系统的创新性三、居民的便捷体验四、面临的挑战 前言 在科技快速发展的今天&#xff0c;智能化和数字化已经深刻影响着我们的生活的各个方面。近期备受关注的话题之一是二维码智慧门牌管理系统&#xff0c;这一系统…

1 tcp协议20问

1什么是TCP网络分层 1.1分层描述 网络访问层&#xff1a; 2 TCP的三次握⼿中为什么是三次&#xff1f;为什么不是两次、四次&#xff1f; 两次握手的话&#xff0c;服务端会单方面认为建立已经成功&#xff0c;但是对于客户端而言&#xff0c;可能只是开个玩笑的&#xff0c…

[人工智能-综述-12]:第九届全球软件大会(南京)有感 -1-程序员通过大模型增强自身软件研发效率的同时,也在砸自己的饭碗

目录 前言&#xff1a; 一、什么是软件工程 1.1 什么软件工程 1.2 影响软件开发效能的三大因素 1.3 AI大模型是如何提升软件工程全过程效率的 二、AI大模型如何提升软件项目管理效率 2.1 概述 2.2 案例或工具 三、AI大模型如何提升软件开发工具的效率 3.1 概述 3.2 …

蓝桥每日一题(day 3: 蓝桥587.约数个数)--数学--easy

题目 解题核心&#xff1a; 分解质因数&#xff0c;每个质因数的次方1的累乘积就是anscode #include <iostream> #include<algorithm> #include<unordered_map> //# #include<> typedef long long LL; const int N 110, MOD 1e9 7;using namespac…

小程序原生代码转uniapp

写了一份小程序原生代码&#xff0c;想转为uniapp 再转为其他平台发布 1、在命令行里&#xff0c;运行【 npm install miniprogram-to-uniapp -g 】进行安装&#xff0c;因为这个包是工具&#xff0c;要求全局都能使用&#x…