MVP开发模式解析

article/2025/9/23 1:27:14



前言

由于项目里同事用到MVP开发模式,我看了几篇关于 MVP 的文章,对其有了基本的了解之后,便照猫画虎进行了开发,之后便再也没接触过 MVP。

最近空闲读了些MVP的文章,受益匪浅,于是打算写一篇关于MVP开发的文章,一方面作为自己学习的笔记便于查看,另一方面希望能帮助没有接触过 MVP 模式的新人提供帮助,以便可以快速入门。

什么是MVC

在讲MVP之前先讲讲MVC

MVC结构图

MVC即Model-View-Controller。M:逻辑模型,V:视图模型,C:控制器。

Model 层:用来定义实体对象,处理业务逻辑,可以简单地理解成 Java 中的实体类。

View 层:负责处理界面的显示,在 Android 中对应的就是 xml 文件。

Controller 层:对应的是 Activity/Fragment ,当加载完成 xml 布局之后,我们需要找到并设置布局中的各个 View,处理用户的交互事件,更新 View 等。

在MVC模式中,Controller扮演者重要的角色,它不仅要处理 UI 的显示与事件的响应,还要负责与 Model 层的通信,同时 Model 层与 View 层也会通信,三者的耦合度很大。

作为安卓中默认的开发模式,MVC易于上手,适合快速开发小型项目,但是随着业务逻辑的复杂度越来越大,View(Activity/Fragment)层代码就会越来越臃肿,因为它同事承担着Controller 与 View 的角色,这对于项目后期的更新维护与测试交接都是非常不方便的,大大提高了生产成本,于是MVP就应运而生。

什么是MVP

MVP结构图

MVP是MVC的升级进化,全称Model(模型层)、View(视图层)、Presenter(主持者)。从结构图中我们可以看到,Presenter直接替代了Controller,去除了了Model与View的直接关联与耦合

Model 层:与MVC中的Model层一样,用来定义实体对象,处理业务逻辑

View 层:视图层,在MVP模式中不仅对应 xml 文件, Activity/Fragment也属于视图层,View 层现在不仅作为 UI 的显示,还负责响应生命周期的变化

Presenter层:主持者层,Model层与View层沟通的桥梁,处理业务逻辑,它响应View的请求从Model层获取数据,再将数据返回给View层,View实现Ui更新。

在 MVP 的架构中,最大的特点就是 View 与 Model 之间的解耦,两者之间必须通过 Presenter 来进行通信,使得视图和数据之间的关系变得完全分离。

MVP的基本实现方式

1.创建Presenter接口,把所有的业务逻辑接口放在这里,并创建它的实现类PresenterImpl

2.创建Iview接口,把所有视图逻辑的接口都放在这里,它的实现类是Activity/Fragment

3.在Activity/Fragment中包含了一个Presenter实例,而PresenterImpl又包含了一个IView的实例,并且依赖Model,Activity/Fragment 只保留对 IPresenter 的调用,当 View 层发生某些请求响应或者生命周期发生变化,则会迅速的向 Presenter 层发起请求,让 Presenter 做出相应的处理。

现在我们用MVP模式具体实现它

Presenter接口

public interface MainPresenter {void onResume(MainActivity mainActivity);//页面初始化,Presenter 被激活void onDestory();//页面结束,Presenter 结束,为了避免相互持有引用而导致的内存泄露void loadMore(MainActivity mainActivity);//加载更多
}

IView 接口:

public interface MainView {void onNext(String resulte, String mothead); //拿到model层返回的数据,实现UI的显示void onError(ApiException e);//失败异常处理void showLoadingDialog();//显示加载网络的弹框void dialogDissmiss();//网络请求成功或失败,结束加载网络的弹框
}

Presenter接口的实现类

public class MainPresenterImpl implements MainPresenter, MainInteractor.OnGetDataResultFinishListener {private MainView mainView;private MainInteractorImpl mainInteractor;public MainPresenterImpl(MainView mainView, MainInteractorImpl mainInteractor) {this.mainView = mainView;this.mainInteractor = mainInteractor;}@Overridepublic void onNext(String resulte, String mothead) {if (mainView != null) {mainView.onNext(resulte, mothead);mainView.dialogDissmiss();}}@Overridepublic void onError(ApiException e) {}@Overridepublic void onResume(MainActivity mainActivity) {if (mainView != null) mainView.showLoadingDialog();SubjectApi postEntity = new SubjectApi();postEntity.setStart(0);postEntity.setAreaId("");postEntity.setMothed("SSLJ_CORE_PLATFORM/circles/datatable" + "/" + 0);mainInteractor.getDataResult(this, postEntity, mainActivity);}@Overridepublic void onDestory() {mainView = null;}@Overridepublic void loadMore(MainActivity mainActivity) {SubjectApi postEntity = new SubjectApi();postEntity.setStart(0);postEntity.setAreaId("");postEntity.setMothed("SSLJ_CORE_PLATFORM/circles/datatable" + "/" + 0);mainInteractor.getDataResult(this, postEntity, mainActivity);}
}

IView 接口的实现类 MainActivity

 public class MainActivity extends RxAppCompatActivity implements MainView,    RecyclerArrayAdapter.OnLoadMoreListener {private LinearLayoutManager linearLayoutManager;private SnsBlogAdapter adapter;private MainPresenter mainPresenter;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);initView();initData();}private void initView() {ActivityMainTestBinding binding = DataBindingUtil.setContentView(this, R.layout.activity_main_test);linearLayoutManager = new LinearLayoutManager(this);binding.recyclerView.setLayoutManager(linearLayoutManager);binding.recyclerView.setAdapter(adapter = new SnsBlogAdapter(this));adapter.setMore(R.layout.view_more, this);adapter.setOnItemClickListener(new RecyclerArrayAdapter.OnItemClickListener() {@Overridepublic void onItemClick(int position) {}});adapter.setError(R.layout.view_error, new RecyclerArrayAdapter.OnErrorListener() {@Overridepublic void onErrorShow() {adapter.resumeMore();}@Overridepublic void onErrorClick() {adapter.resumeMore();}});}private void initData() {mainPresenter = new MainPresenterImpl(this, new MainInteractorImpl());mainPresenter.onResume(this);}@Overrideprotected void onDestroy() {super.onDestroy();mainPresenter.onDestory();}@Overridepublic void onLoadMore() {mainPresenter.loadMore(this);}@Overridepublic void onNext(String resulte, String mothead) {Gson gson=new Gson();List<SnsCard> items = gson.fromJson(resulte, new TypeToken<List<SnsCard>>() {}.getType());adapter.addAll(items);}@Overridepublic void onError(ApiException e) {}@Overridepublic void showLoadingDialog() {Toast.makeText(this, "正在加载", Toast.LENGTH_SHORT).show();}@Overridepublic void dialogDissmiss() {Toast.makeText(this, "加载完成", Toast.LENGTH_SHORT).show();}
}

Model层

public class SnsCard {private String userName;public SnsCard(String userName) {this.userName=userName;}public String getUserName() {return userName;}public void setUserName(String userName) {this.userName = userName;}
}

model 具体业务逻辑的实现

public class MainInteractorImpl implements MainInteractor,HttpOnNextListener {@Overridepublic void getDataResult(final OnGetDataResultFinishListener listener, SubjectApi baseApi, MainActivity rxAppCompatActivity) {new Handler().postDelayed(new Runnable() {@Override public void run() {Gson gson = new Gson();String str = gson.toJson(createSnsCardList());listener.onNext(str,"");}}, 2000);
//        new HttpManager(this,rxAppCompatActivity).doHttpDeal(baseApi);}private List<SnsCard> createSnsCardList() {List<SnsCard> SnsCards=new ArrayList<>();for (int i = 0; i <10 ; i++) {SnsCards.add(new SnsCard("jerry"+i));}return SnsCards;}@Overridepublic void onNext(String resulte, String mothead) {}@Overridepublic void onError(ApiException e) {}
}

Model提供给Presenter层调用的接口和提供返回数据给Presenter层的接口

public interface MainInteractor {interface OnGetDataResultFinishListener{/*** 成功后回调方法** @param resulte* @param mothead*/void onNext(String resulte, String mothead);/*** 失败* 失败或者错误方法* 自定义异常处理** @param e*/void onError(ApiException e);}//获取网络数据void getDataResult(OnGetDataResultFinishListener listenter, SubjectApi baseApi, MainActivity rxAppCompatActivity);
}

看完代码有人会发现,相对于MVC模式来说,代码不仅没有减少,反而增加了许多接口,看起来有点晕,但仔细观察可以看到MVP的结构是非常清晰的。

下面我们仔细分析一下

MainActivity 实现了MainView接口,并实现了 onNext(..) , onError(..),showLoadingDialog(..)和dialogDissmiss(..) 这4个方法,但是这4个方法看起来好像都没有被调用,只是在 onCreate() 的时候创建了一个 MainPresenterImpl 对象,然后在 onDestroy() 的时候调用了 mPresenter.destroy() 方法, 在onCreate()里调用了 mainPresenter.onResume(..) 方法,那么既没有回调也没有直接调用,那 MainView 中的4个接口方法又是何时何地被调用的呢?接下来我们将继续分析 Presenter 层的实现代码。

在 MainPresenterImpl 中实现了 MainPresenter 接口并实现了 onResume(..) loadMore(..) onDestory(..) 方法,在构造方法中有一个MainView的参数,这个对象是 MainView 的引用,这个对象可以是 Activity 或者是 Fragment 也可以是 MainView 接口的任何一个实现类,但对于 MainPresenterImpl 而言具体的 IView 到底是谁并不知道。在 MainPresenterImpl 中,在 onResume(..)方法中除了调用 Model 外和MainView 的方法外,其他方法都调用了MainView接口提供的方法,以此来对 View 层的 UI 呈现以及交互提醒做出相应的响应。而最后的 onDestory(..) 方法则是用于释放对 IView 的引用。

因此我们得出结论:

对于View而言

我需要一位主持者,当出现视图相关事件的响应或者生命周期的变化时,我需要告诉这位主持者,我想要做些什么。

我会提供一系列通用接口,以便于当主持者完成我的请求后,调用相应的接口告诉我这件事的结果。

我所有的请求都发给主持者,让他帮我做决定,但是这件事是怎么做的,我并不知道也不关心,我只是需要结果。

对于 Presenter 而言:

我接收到 View 的请求后找 Model 寻求帮助,等 Model 做完事情后通知我了,我在把结果告诉 View。

我只知道指挥 Model做事、告诉 View 显示数据,但我不干活。

我相当于一座桥,连接着 View 和 Model,他们谁也不认识谁,想要通信必须要通过我,如果没有我,他们两永远都不会认识。没错,我就是这么重要。

由于有 Presenter的存在,View层代码看起来非常清晰,每个方法都有他自己的功能职责,彼此之间并不会相互耦合而 Presenter 中的代码也是如此,每一个方法都只处理一件事,并不会做其他无相关的事情。另外我们观察到,在 MainActivity 中并没有直接对 MainPresenterImpl 进行持有,而是持有了一个 MainPresenter 对象;同样的在 MainPresenterImpl 也并没有直接持有 MainActivity 而是持有了一个 IView 对象。也就是说,凡是实现了 MainPresenter 便是 Presenter 层,凡是实现了 MainView 便是 View 层,这样就能很方便地变更业务逻辑或者进行单元测试。

本篇博客示例代码: https://github.com/jerryyh/MvpAndroidmaster


http://chatgpt.dhexx.cn/article/ocOhA0CN.shtml

相关文章

MVP模式的优缺点

MVP模式是MVC的一个演化版本&#xff0c;全称是Model view Presenter。 MVP能够有效的降低View的复杂性&#xff0c;避免业务逻辑被塞进View中,使得View变成一个混乱的“大泥坑”。 MVP模式会解除View与Model的耦合&#xff0c;同时又带来了良好的可扩展性&#xff0c;可测试…

Android MVP开发模式 google 官方Mvp架构详解(转)

Google官方MVP Sample代码解读 关于Android程序的构架, 当前最流行的模式即为MVP模式, Google官方提供了Sample代码来展示这种模式的用法.Repo地址: android-architecture.本文为阅读官方sample代码的阅读笔记和分析. 官方Android Architecture Blueprints [beta]:Android在如…

MVP模式的相关知识

MVP 是从经典的模式MVC演变而来&#xff0c;它们的基本思想有相通的地方&#xff1a;Controller/Presenter负责逻辑的处理&#xff0c;Model提供数据&#xff0c;View负责显示。作为一种新的模式&#xff0c;MVP与MVC有着一个重大的区别&#xff1a;在MVP中View并不直接使用Mod…

【iOS】MVP模式

文章目录 什么是MVP模式&#xff1f;图解 从MVC到MVP苹果的MVC为何要从MVC到MVP?MVP MVP模式下的工程MVP模式的优缺点 什么是MVP模式&#xff1f; MVP模式是MVC模式的一个演化版本&#xff0c;MVP全称Model-View-Presenter。&#xff08;关于MVC模式可见这篇文章&#xff09; …

浅谈安卓中的MVP模式

端午放假&#xff0c;天气下雨&#xff0c;于是乎在家撸一下博客&#xff0c;本篇博客将为大家解析MVP模式在安卓中的应用。 本文将从以下几个方面对MVP模式进行讲解&#xff1a; 1. MVP简介 2. 为什么使用MVP模式 3. MVP模式实例 4. MVP中的内存泄露问题 1. MVP简介&…

Android MVP模式 入门

1.前言 近些年来&#xff0c;Android架构模式有很多&#xff0c;我们比较熟知的有MVC&#xff0c;MVP以及MVVM&#xff0c;目前Android市场中使用最多的应该是MVP架构&#xff0c;虽然MVVM结合DataBing看似更加方便&#xff0c;但在一般公司中使用的还是比较少。其实模式这种东…

MVP模式实例解释

为什么在UI层包含太多的逻辑是很糟糕的&#xff1f;在既不手动运行应用程序&#xff0c;也不维护丑陋的自动执行UI组件的UI运行者脚本(runner script)的情况下&#xff0c;位于应用程序UI层中的代码是非常难于调试的。虽然这本身就是一个很大的问题&#xff0c;一个更大的问题是…

Android开发之MVP模式

前言&#xff1a;在之前的开发中一直用的是mvc模式搭建的项目&#xff0c;所以我对于mvp也一直只是停留在理论和demo阶段上。正好现在的项目是被小伙伴借助dragger搭建的mvp模式的结构&#xff0c;所以就想着总结整理一下mvp模式的东西并写出来&#xff0c;也算是作为自己使用了…

MVP模式与MVC模式

源地址&#xff1a;http://www.cnblogs.com/cuihongyu3503319/archive/2009/01/09/1372820.html MVP模式与MVC模式(转) MVP 是从经典的模式MVC演变而来&#xff0c;它们的基本思想有相通的地方&#xff1a;Controller/Presenter负责逻辑的处理&#xff0c;Model提供数据&#x…

MVP模式从入门到精通

首先附上自己写的一个MVP的demo&#xff0c;这是一个很标准的MVP&#xff0c;Github地址如下&#xff1a; https://github.com/SilasGao/MVPDemo 首先MVP 是从经典的MVC架构演变而来&#xff0c;那我们是不是要先说下何为MVC模式&#xff1f; 系统C/S(Client/Server)三层架构模…

MVP模式使用示例详解

什么是MVP模式? 这个MVP可不是腾讯游戏《王者荣耀》中的MVP。我们今天要讨论的MVP其实同MVC一样&#xff0c;是一种编程模式和思想&#xff0c;也许更准确地讲是一种架构。 MVP和MVC的区别 提到MVP模式&#xff0c;大家自然避免不了要和我们以前常用的MVC模式进行对…

MVP设计模式

Model–view–presenter (MVP) 是model–view–controller (MVC)设计模式派生出来的。MVP经常用来创建用户界面。 presenter是作为一个“中间人”的角色存在。在MVP中&#xff0c;所有页面显示逻辑都会被推送到presenter。 以下这张图是MVC模式的&#xff1a; MVP与MVC有着一…

Android中用到的MVP模式

参考&#xff1a;android架构设计—mvp模式封装 很简单&#xff0c;M&#xff1a;数据&#xff0c; V:界面&#xff0c; P:一个使唤数据(M)和界面(V)干活的大管家。 特点&#xff1a;在P的管理下&#xff0c;P可以直接支配V和M做一些事情。但是V&#xff0c;与M&#xff0c;你…

Android MVP模式 简单易懂的介绍方式

Android MVP Pattern Android MVP 模式1 也不是什么新鲜的东西了&#xff0c;我在自己的项目里也普遍地使用了这个设计模式。当项目越来越庞大、复杂&#xff0c;参与的研发人员越来越多的时候&#xff0c;MVP 模式的优势就充分显示出来了。 导读&#xff1a;MVP模式是MVC模式在…

Android MVP模式详解

一、MVP概述 MVP&#xff0c;全称 Model-View-Presenter&#xff0c;即模型-视图-层现器。 提到MVP&#xff0c;就必须要先介绍一下它的前辈MVC&#xff0c;因为MVP正是基于MVC的基础发展而来的。两个之间的关系也是源远流长。 MVC&#xff0c;全称Model-View-Controller&am…

浅谈安卓MVP模式

本篇博文通过对google官方demo&#xff1a;https://github.com/googlesamples/android-architecture/tree/todo-mvp/的理解&#xff0c;用自己的demo更好的讲解mvp的概念&#xff0c;帮助大家如何针对一个Activity页面去编写针对MVP风格的代码。 一、MVP模式介绍 随着UI创建技…

简单易懂 MVP 模式

Android MVP 模式 [1] 也不是什么新鲜的东西了&#xff0c;我在自己的项目里也普遍地使用了这个设计模式。当项目越来越庞大、复杂&#xff0c;参与的研发人员越来越多的时候&#xff0c;MVP 模式 的优势就充分显示出来了。 MVP 模式是 MVC 模式在 Android 上的一种变体&#…

深入浅出——MVP模式

由于公司里的架构模式用到MVP&#xff0c;觉得自己还不够熟悉&#xff0c;决定在此理一理&#xff0c;并给大家一起总结下。 一 MVP模式介绍 MVP全称Model View Presenter。 MVP能够有效的降低View的复杂性&#xff0c;避免业务逻辑被塞进View中&#xff0c;防止View的代码变…

MVP模式简单讲解,通俗易懂

了解 MVP 和 MVC 的区别 https://baike.baidu.com/item/MVP/3714550?fraladdin 什么是MVP&#xff1a; MVP 是 MVC 的变种&#xff0c;其实是一种升级。要说 MVP 就要说说 MVC&#xff0c;在 MVC 中 Activity 其实是 View层级&#xff0c;但是通常在使用中 Activity即是View…

MVP框架模式

一、基本概念 MVP是Model-View-Presenter的简称&#xff0c;即模型-视图-表现层的缩写。MVP是由MVC模式进化而来的&#xff0c;MVP改进了MVC中的控制器过于臃肿的问题。 与MVC一样&#xff0c;MVP将应用程序的数据处理、数据显示和逻辑控制分开&#xff0c;用一种业务逻辑、数…