android开发中mvp与mvc的差别,如何使mvp(demo)
来源:互联网 发布:js里能生成uuid吗 编辑:程序博客网 时间:2024/06/05 04:38
什么是MVP架构,mvp与mvc的差别
MVP就是Model-View-Presenter,MVP是从经典的模式MVC演变而来,它们的基本思想有相通的地方:Controller/Presenter负责逻辑的处理,Model提供数据,View负责显示。作为一种新的模式,MVP与MVC有着一个重大的区别:在MVP中View并不直接使用Model,它们之间的通信是通过Presenter (MVC中的Controller)来进行的,所有的交互都发生在Presenter内部,而在MVC中View会直接从Model中读取数据而不是通过 Controller。
在MVC里,View是可以直接访问Model的!从而,View里会包含Model信息,不可避免的还要包括一些业务逻辑。 在MVC模型里,更关注的Model的不变,而同时有多个对Model的不同显示,及View。所以,在MVC模型里,Model不依赖于View,但是View是依赖于Model的。不仅如此,因为有一些业务逻辑在View里实现了,导致要更改View也是比较困难的,至少那些业务逻辑是无法重用的。
用流程图的方式解释就更清楚了:
MVP和MVC的区别,及MVP是如何解决MVC的问题?
MVP架构:
View: 对应于Activity,负责View的绘制以及与用户交互
Model: 依然是业务逻辑和实体模型
Presenter: 负责完成View于Model间的交互
View不直接与Model交互,而是通过与Presenter交互来与Model间接交互。
Presenter与View的交互是通过接口来进行的。
通常View与Presenter是一对一的,但复杂的View可能绑定多个Presenter来处理逻辑。
MVC架构:
View:对应于布局文件
Model:业务逻辑和实体模型
Controllor:对应于Activity
View可以与Model直接交互。
Controller是基于行为的,并且可以被多个View共享。
可以负责决定显示哪个View。
总结解释一下就是说:从MVC到MVP的一个转变,就是减少了Activity的职责,减轻了它的负担,简化了Activity中的代码和一些操作,将逻辑代码提取到了Presenter中进行处理,降低了其耦合度。
进一步的解释:
在MVP里,Presenter完全把Model和View进行了分离,主要的程序逻辑在Presenter里实现。而且,Presenter与具体的View是没有直接关联的,而是通过定义好的接口进行交互,从而使得在变更View时候可以保持Presenter的不变,即重用! 不仅如此,我们还可以编写测试用的View,模拟用户的各种操作,从而实现对Presenter的测试--而不需要使用自动化的测试工具。 我们甚至可以在Model和View都没有完成时候,就可以通过编写Mock Object(即实现了Model和View的接口,但没有具体的内容的)来测试Presenter的逻辑。 在MVP里,应用程序的逻辑主要在Presenter来实现,其中的View是很薄的一层。因此就有人提出了Presenter First的设计模式,就是根据User Story来首先设计和开发Presenter。在这个过程中,View是很简单的,能够把信息显示清楚就可以了。在后面,根据需要再随便更改View,而对Presenter没有任何的影响了。 如果要实现的UI比较复杂,而且相关的显示逻辑还跟Model有关系,就可以在View和Presenter之间放置一个Adapter。由这个 Adapter来访问Model和View,避免两者之间的关联。而同时,因为Adapter实现了View的接口,从而可以保证与Presenter之间接口的不变。这样就可以保证View和Presenter之间接口的简洁,又不失去UI的灵活性。 在MVP模式里,View只应该有简单的Set/Get的方法,用户输入和设置界面显示的内容,除此就不应该有更多的内容,绝不容许直接访问Model--这就是与MVC很大的不同之处。
MVP的优点
1.降低耦合度,隐藏数据,Activity中代码更简洁
2.模块职责划分明显
3.方便测试驱动开发
4.代码复用度较高
5.代码灵活性
现在来实操下吧,附上demo如下:
这个实例是根据用户id获取用户信息并展示的一个过程,其中获取用户信息用了一个线程进行了模拟获取。希望大家能够看懂,并对大家有所帮助。
我们先看一下MVP目录结构图
1、先说下Model层吧
首先是一个javabean UserBean实体类
public class UserBean { private String name; private String id; private String sex; private String age; public String getName() { return name; } public void setName(String name) { this.name = name; } public String getId() { return id; } public void setId(String id) { this.id = id; } public String getSex() { return sex; } public void setSex(String sex) { this.sex = sex; } public String getAge() { return age; } public void setAge(String age) { this.age = age; } @Override public String toString() { return "UserBean{" + "name='" + name + '\'' + ", id='" + id + '\'' + ", sex='" + sex + '\'' + ", age='" + age + '\'' + '}'; }}
Model层抽象接口实现:
/** * Created by txh on 2017/4/22. * Model实现接口IGetUser,在这个接口的现实方法里请求并获取数据, * 并赋值成功与失败的监听OnUserInfoListener, * 方便presenter通过接口IGetUser获取成功失败的信息 */public class GetUserInfoModel implements IGetUser { @Override public void getUserInfo(final int id, final OnUserInfoListener listener) { new Thread(){ @Override public void run() { try { Thread.sleep(2000); } catch (InterruptedException e) { e.printStackTrace(); } if (id == 1){// 模拟信息获取成功 UserBean userBean = new UserBean(); userBean.setName("txh"); userBean.setAge("25"); userBean.setSex("女"); userBean.setId("1"); listener.getUserInfoSuccess(userBean); }else {// 模拟信息获取失败 listener.getUserInfoFailed(); } } }.start(); }}
Model层抽象接口:
2、View层
我们都知道Presenter与View交互是通过接口,所以我们需要定义一个IShowUserView的接口,这个接口封装的方法基本上都跟视图展示有关。
3、Presenter层
Presenter是Model和View之间交互的桥梁,里面有一些业务逻辑的操作。
public class UserInfoPresenter { private final IShowUserView iShowUserView; private final IGetUser iGerUser; private Handler mHandler = new Handler(); public UserInfoPresenter(IShowUserView iShowUserView) { this.iShowUserView = iShowUserView; //通过构造传入接口IShowUserView this.iGerUser = new GetUserInfoModel();//给接口赋值,初始Model层数据 } public void getUserInfoToShow(int id){ iShowUserView.showLoading(); iGerUser.getUserInfo(id, new OnUserInfoListener() { @Override public void getUserInfoSuccess(final UserBean user) { //耗时操作,开线程 mHandler.post(new Runnable() { @Override public void run() { iShowUserView.toMainActivity(user); iShowUserView.hideLoading(); } }); } @Override public void getUserInfoFailed() { //耗时操作,开线程 mHandler.post(new Runnable() { @Override public void run() { iShowUserView.showFailedError(); iShowUserView.hideLoading(); } }); } }); }}
4、Activity中的调用
public class MainActivity extends Activity implements IShowUserView{ private Button btn; private ProgressDialog pd; private UserInfoPresenter userInfoPresenter; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); //初始Presenter层,准备数据,通过传入的接口展示 userInfoPresenter = new UserInfoPresenter(this); btn = ((Button) findViewById(R.id.btn)); pd = new ProgressDialog(this); pd.setMessage("正在加载..."); btn.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { userInfoPresenter.getUserInfoToShow(1); } }); } @Override public void showLoading() { pd.show(); } @Override public void hideLoading() { pd.hide(); } @Override public void toMainActivity(UserBean userBean) { Toast.makeText(this,userBean.getName()+":"+userBean.getAge()+"-" +userBean.getSex(),Toast.LENGTH_LONG).show(); } @Override public void showFailedError() { Toast.makeText(this,"获取信息有误",Toast.LENGTH_SHORT).show(); }}
最后,看完后,记得练习下哟!
- android开发中mvp与mvc的差别,如何使mvp(demo)
- 两张图看懂Android开发中MVC与MVP的区别
- android MVC与MVP
- Android MVP与MVC
- Android---MVP模式介绍,以及MVP与MVC的区别
- Android开发中逐步取代MVC的MVP架…
- 浅谈Android中MVP模式与MVC模式的区别
- Android中Mvp与Mvc模式的区别
- MVP与MVC的区别 in Android
- Android中MVC,MVP,MVVM的区别
- Android开发模式MVP,MVC
- Android中的MVC与MVP
- 浅谈Android开发中内存泄露与优化与框架模式之MVC与MVP
- MVP 与MVC 的区别
- MVC与MVP的区别
- MVP与MVC的异同
- mvc与mvp的区别
- MVP与MVC的区别
- java基础总结14-面向对象10(多态)
- Docker for Windows 中文文档(2)——Set up tab completion in PowerShell
- lintode(108)分割回文串 II
- pymongo 存取
- Matlab编程 二维图形绘制进阶
- android开发中mvp与mvc的差别,如何使mvp(demo)
- 数据准备-在编码格式上摔的坑
- ubuntu如何安装jenkins
- C# 网页sapx页面调用用户邮箱客户端
- 树和二叉树
- 简单的递归题目
- hiveSQL操作
- SAS中的删除空格相关函数
- 正则表达式-如何从一个字符串中拿到特定内容