转载请注明本文出自Cym的博客(http://blog.csdn.net/cym492224103),谢谢支持!


什么是MVP呢?它又和我们常常听到的MVC有什么关系了以及区别呢?

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里,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、模型与视图完全分离,我们可以修改视图而不影响模型
2、可以更高效地使用模型,因为所有的交互都发生在一个地方——Presenter内部
3、我们可以将一个Presenter用于多个视图,而不需要改变Presenter的逻辑。这个特性非常的有用,因为视图的变化总是比模型的变化频繁。
4、如果我们把逻辑放在Presenter中,那么我们就可以脱离用户接口来测试这些逻辑(单元测试)

那么说了这么多又关于MVP的东西那么该如何写一个MVP的项目呢?请看下图:

先从项目目录结构上面来看
我们模拟一个需求:首先我们要进入一个 Splash界面, Splash界面中,有一个

ProgressBar控件和TextView控件,我们判断它是否有网络连接,如果有的话就隐藏  ProgressBar和跳转到MainActivity如果没有网络的话则显示ProgressBar和TextView,TextView则提示用户No internet。就这么简单的一个需求,我们看看如何用MVP模式做这个需求

首先我们看下M层是如何接口写的

package com.manning.androidhacks.hack020.presenter.model;public interface IConnectionStatus {boolean isOnline();
}

然后看看实现(我们主要是看MVP模式的使用,所以在此就不做网络连接的检查了,模拟一个状态)

package com.manning.androidhacks.hack020.presenter.model.impl;import com.manning.androidhacks.hack020.presenter.model.IConnectionStatus;public class ConnectionStatus implements IConnectionStatus {@Overridepublic boolean isOnline() {// TODO: Here we should place the code to check the connectivity.return true;}}

然后我们在来看看V的接口

package com.manning.androidhacks.hack020.view;public interface ISplashView {void showProgress();void hideProgress();void showNoInetErrorMsg();void moveToMainView();
}

以及V的实现

package com.manning.androidhacks.hack020.view.impl;import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.ProgressBar;
import android.widget.TextView;import com.manning.androidhacks.hack020.R;
import com.manning.androidhacks.hack020.presenter.SplashPresenter;
import com.manning.androidhacks.hack020.view.ISplashView;public class SplashActivity extends Activity implements ISplashView {private TextView mTextView;private ProgressBar mProgressBar;private SplashPresenter mPresenter = new SplashPresenter();@Overridepublic void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.splash);mPresenter.setView(this);mTextView = (TextView) findViewById(R.id.splash_text);mProgressBar = (ProgressBar) findViewById(R.id.splash_progress_bar);}@Overrideprotected void onResume() {super.onResume();mPresenter.didFinishLoading();}public void showProgress() {mProgressBar.setVisibility(View.VISIBLE);}public void hideProgress() {mProgressBar.setVisibility(View.INVISIBLE);}public void showNoInetErrorMsg() {mTextView.setText("No internet");}@Overridepublic void moveToMainView() {startActivity(new Intent(this, MainActivity.class));}
}

最后我们来看看P层是如何控制他们的逻辑的:

public class SplashPresenter {private IConnectionStatus mConnectionStatus;private ISplashView mView;public SplashPresenter() {this(new ConnectionStatus());}public SplashPresenter(IConnectionStatus connectionStatus) {mConnectionStatus = connectionStatus;}public void setView(ISplashView view) {this.mView = view;}protected ISplashView getView() {return mView;}public void didFinishLoading() {ISplashView view = getView();if (mConnectionStatus.isOnline()) {view.showProgress();view.moveToMainView();} else {view.hideProgress();view.showNoInetErrorMsg();}}
}

好,我个人理解,就是把逻辑层抽出来成P层,要是遇到需求逻辑上的更改就可以只需要修改P层了或者遇到逻辑上的大概我们可以直接从写一个P也可以,现在我看过的大多数开发把所有的东西都写在了Activity里面这样一来遇到改频繁改需求的时候,Activity里面就会被写的乱糟糟,所以想到了这个MVP模式希望能帮助到大家 ,大家是不是觉得MVP很不错呢?觉得不错的同学们就应用到你的实战开发中去吧~!

ym——Android开发MVP模式(解决了View和Model的耦合)相关推荐

  1. Android开发MVP模式(解决了View和Model的耦合)

    转载请注明本文出自Cym的博客(http://blog.csdn.net/cym492224103),谢谢支持! 什么是MVP呢?它又和我们常常听到的MVC有什么关系了以及区别呢? MVP 是从经典的 ...

  2. Android开发MVP模式--项目实战

    1 前言 苏宁+App是苏宁易购集团零售云研发中心分销研发中心主要产品之一,由于项目处于初期阶段,业务逻辑复杂,导致业务需求变动快,常常在开发甚至测试过程中出现界面或者后台接口调整的情况. App客户 ...

  3. Android之MVP模式

    今天来看看Android的MVP模式,使用框架开发,开发速度以及代码的目录结构会别有一番风格. Google的demo:https://github.com/googlesamples/android ...

  4. android viewpager fragment传值,Android开发中如何解决Fragment +Viewpager滑动页面重复加载的问题...

    前言 之前在做一个Viewpager上面加载多个Fragment时总会实例化已经创建好的Fragmnet对象类似 viewPager.setAdapter(new FragmentPagerAdapt ...

  5. android开发mvp,Android开发模式之MVP

    一. 什么是MVP MVP 是从经典的模式MVC演变而来,它们的基本思想有相通的地方:Controller/Presenter负责逻辑的处理,Model提供数据,View负责显示. 二.MVP与MVC ...

  6. android 适合mvp模式,Android中的MVP:如何使Presenter层系统化?

    MVP(Model View Presenter)模式是著名的 MVC(Model View Controller)的衍生物,并且是 Android 应用程序中管理表示层的***的模式之一. 这篇文章 ...

  7. Android之MVP 模式:简单易懂的介绍方式

    转载:https://segmentfault.com/a/1190000003927200 Android MVP Pattern Android MVP 模式1 也不是什么新鲜的东西了,我在自己的 ...

  8. android 的MVP模式的介绍

    当下开发中使用最多的最普遍的有三种模式就是MVC,MVP和MVVM.相信大家对这三个名词并不陌生,他们在我们的开发用应用的及其广泛,今天我就浅谈一下我了解的MVP设计模式.说MVP之前不得不谈谈MVC ...

  9. android MVP连接服务器,Android之MVP模式实现登陆和网络数据加载

    MVP简介 相信你们对 MVC 都是比较熟悉了:M-Model-模型.V-View-视图.C-Controller-控制器,MVP做为MVC的演化版本,也是做为用户界面(用户层)的实现模式,那么相似的 ...

最新文章

  1. 谷歌浏览器扩展程序XDM_请立即更新您的谷歌Chrome浏览器 获取重要的安全补丁程序...
  2. 网站关键词优化有哪些技巧?
  3. 第二十四章:页面导航(五)
  4. zabbix学习小结
  5. 对‘TIFFReadDirectory@LIBTIFF_4.0’未定义的引用
  6. Java 8 Stream中间操作(方法)示例
  7. 窗体案例:注册 登陆 主界面 c# 1613533126
  8. FASTQ format
  9. 获取当地天气_6 点起来看天气预报?正经人谁看天气预报,原来是为了看她
  10. 47. Python socket编程 2
  11. 阿里云CentOS环境之docker安装,启动,加速器,docker-compose(十四)
  12. 惠普服务器装系统ESXI,在惠普服务器上安装ESXI 5.5卡在LSI_MR3.V00的解决方案
  13. Binutils - c++filt工具
  14. 无法设置默认打开方式怎么办
  15. 软件测试学习资料大全
  16. 5、流程变量Variables
  17. HPE MSA存储的高性能连接解决方案
  18. 一个屌丝程序猿的人生(五十一)
  19. 高精度地图,从入门到入行
  20. 寺库拟私有化:报价较发行价缩水75%,趣店为第一大股东

热门文章

  1. Python语言系统学习21:作品——简易计算器
  2. Qt几个月的学习心得及展望
  3. java全栈系列之JavaSE-面向对象(方法的定义与调用)030
  4. CentOS7系统下Java环境和tomcat的安装
  5. 通过键盘wasd的的点击使按钮移动,通过点击移动按钮
  6. iconfont阿里图标引入不生效的解决方法,三种引入方式详细步骤。
  7. 张益唐111页论文攻克朗道-西格尔零点猜想
  8. 2016年国内开源镜像站点汇总
  9. python 迅雷 批量下载电影天堂电影
  10. matlab的给平面图,matlab画相平面图