浅谈MVP实现Android应用层开发

PS一句:最终还是选择CSDN来整理发表这几年的知识点,该文章平行迁移到CSDN。因为CSDN也支持MarkDown语法了,牛逼啊!

【工匠若水 http://blog.csdn.net/yanbober

背景

之所以要谈这个话题是因为你在开发App时可能会发现,Activity担负的责任非常之重,如果站在MVC框架角度看自己开发的App,一般xml布局文件科Activity的setContentView等充当了View角色,Activity其他代码充当了Controller角色,其他数据来源(数据库等)充当了Model角色。所以你会发现Activity违背单一职责原则,负担过重。同时如果要测试逻辑数据层会发现比较难编写测试用例。由此来构想,有没有一种解耦的方法呢?

有,那就是MVP框架。

MVP架构

MVP就是Model-View-Presenter。其实不用做太多解释,如下图所示你就能明白大致:

如上图所示可以看见MVP模式需要具备如下三要素:

  1. 最左侧的View。也就是Android中的Activity。同时需要创建一个View的抽象接口View interface。需要View实现的接口,View通过View interface与Presenter进行交互,降低耦合。
  2. 最右侧的Model。用来操做实际数据(譬如数据存储等)。有时也需要创建一个Model的抽象接口Model interface用来降低耦合。
  3. 中间的Presenter。作为View与Model交互的中间纽带,处理与用户交互的负责逻辑。

程序猿的纠结—MVP与MVC

看完上面两段,你可能会疑惑MVP,还有一个MVC,他两啥关系?

那再来看下MVC吧!

MVC架构

MVC框架认为软件可以分成如下三个部分:

  • 视图(View):用户界面。
  • 控制器(Controller):业务逻辑。
  • 模型(Model):数据保存。

如下图很直观的展示了MVC框架的核心:

View传送指令到Controller,Controller完成业务逻辑后,要求Model改变状态,Model将新的数据发送到View,用户得到反馈。

MVP与MVC对比

这时候你会发现MVC与MVP的结构图都有很大区别,具体区别如下:

MVP架构:

View不直接与Model交互,而是通过与Presenter交互来与Model间接交互。

Presenter与View的交互是通过接口来进行的。

通常View与Presenter是一对一的,但复杂的View可能绑定多个Presenter来处理逻辑。

MVC架构:

View可以与Model直接交互。

Controller是基于行为的,并且可以被多个View共享。

可以负责决定显示哪个View。

总结

MVC与MVP很相似,但又有很大区别,站在不同分析角度会有不同的观点,这里只是站在基于Android App代码下来分析的结果。

MVP架构的Android应用实战:

完整工程代码点我进入下载页面

背景:如下案例模拟一次用户交互存取数据的过程,用户输入数据后点击保存,然后点击获取数据将保存的数据获取的操作。

UI界面:

工程目录结构:

详细代码:

首先看model层代码,model层提供抽象接口,方便解耦,同时方便测试用例测试model的impl实现代码。如下展示了抽象接口和实现代码。

Model层抽象接口:

public interface IInfoModel {
    //从数据提供者获取数据方法
    InfoBean getInfo();
    //存入数据提供者方法
    void setInfo(InfoBean info);
}

Model层抽象实现:

public class InfoModelImpl implements IInfoModel {
    //模拟存储数据
    private InfoBean infoBean = new InfoBean();

    @Override
    public InfoBean getInfo() {
        //模拟存储数据,真实有很多操作
        return infoBean;
    }

    @Override
    public void setInfo(InfoBean info) {
        //模拟存储数据,真实有很多操作
        infoBean = info;
    }
}

接着看View层代码,View层同样提供抽象接口,方便解耦,同时方便测试用例测试View的impl实现交互代码。如下展示了抽象接口的代码。

View层的抽象接口:

public interface IInfoView {
    //给UI显示数据的方法
    void setInfo(InfoBean info);
    //从UI取数据的方法
    InfoBean getInfo();
}

这个时候其实你可以想想,写UI和逻辑的人可以完全分工,他们通过接口对接。Presenter的角色更像是一个设计模式的适配器类,负责对接UI与数据逻辑。所以不妨先看下Presenter的实现:

public class Presenter {
    private IInfoModel infoModel;
    private IInfoView infoView;

    public Presenter(IInfoView infoView) {
        this.infoView = infoView;

        infoModel = new InfoModelImpl();
    }
    //供UI调运
    public void saveInfo(InfoBean bean) {
        infoModel.setInfo(bean);
    }
    //供UI调运
    public void getInfo() {
        //通过调用IInfoView的方法来更新显示,设计模式运用
        //类似回调监听处理
        infoView.setInfo(infoModel.getInfo());
    }
}

这时候回过头看下View层代码,View层同样实现了View层提供的抽象接口(也就是Activity类,充当UI View)。

如下展示了View层的实现代码:

public class MainActivity extends ActionBarActivity implements IInfoView, View.OnClickListener{
    private EditText inputId, inputName, inputAddr;
    private Button saveBtn, loadBtn;
    private TextView infoTxt;

    private Presenter presenter;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        initData();
    }

    private void initData() {
        presenter = new Presenter(this);

        inputId = (EditText) findViewById(R.id.id_input);
        inputName = (EditText) findViewById(R.id.name_input);
        inputAddr = (EditText) findViewById(R.id.addr_input);
        saveBtn = (Button) findViewById(R.id.input_confirm);
        loadBtn = (Button) findViewById(R.id.get_confirm);
        infoTxt = (TextView) findViewById(R.id.show);

        saveBtn.setOnClickListener(this);
        loadBtn.setOnClickListener(this);
    }

    @Override
    public void setInfo(InfoBean info) {
        StringBuilder builder = new StringBuilder("");
        builder.append(info.getId());
        builder.append("\n");
        builder.append(info.getName());
        builder.append("\n");
        builder.append(info.getAddress());

        infoTxt.setText(builder.toString());
    }

    @Override
    public InfoBean getInfo() {
        InfoBean info = new InfoBean();
        info.setId(Integer.parseInt(inputId.getText().toString()));
        info.setName(inputName.getText().toString());
        info.setAddress(inputAddr.getText().toString());
        return info;
    }

    @Override
    public void onClick(View v) {
        switch (v.getId()) {
            case R.id.input_confirm:
                presenter.saveInfo(getInfo());
                break;
            case R.id.get_confirm:
                presenter.getInfo();
                break;
        }
    }
}

到此解耦并行开发的App编码工作已经完成,如下展示运行结果:

完整工程代码点我进入下载页面

总结

通过上面的例子可以发现,View(Activity)只负责处理用户交互,并把数据相关的逻辑操作都交给了Presenter去做,而Presenter调用Model处理完数据之后,再通过View的抽象接口更新View显示的信息。这样就实现了完整的解耦UI与逻辑操作。

不过,这种观点也是站在App局部代码的角度来分析看待的,对于小型App完全没这个必要,大型的App和交互复杂的可以考虑这么处理,既可以解耦,还可以方便编写test测试代码。

时间: 2024-10-29 22:25:21

浅谈MVP实现Android应用层开发的相关文章

浅谈 MVP in Android(转)

我自己写的demo:https://pan.baidu.com/s/1dFImVYD 一.概述 对于MVP(Model View Presenter),大多数人都能说出一二:“MVC的演化版本”,“让Model和View完全解耦”等等.本篇博文仅是为了做下记录,提出一些自己的看法,和帮助大家如何针对一个Activity页面去编写针对MVP风格的代码. 对于MVP,我的内心有一个问题: 为何这个模式出来后,就能被广大的Android的程序员接受呢? 问了些程序员,他们对于MVP的普遍的认识是:“代

浅谈 MVP in Android

转载请标明出处: http://blog.csdn.net/lmj623565791/article/details/46596109: 本文出自:[张鸿洋的博客] 一.概述 对于MVP(Model View Presenter),大多数人都能说出一二:"MVC的演化版本","让Model和View完全解耦"等等.本篇博文仅是为了做下记录,提出一些自己的看法,和帮助大家如何针对一个Activity页面去编写针对MVP风格的代码. 对于MVP,我的内心有一个问题: 为

浅谈:小程序的开发模式

浅谈:小程序的开发模式 小程序开发,主要可分为三种模式: 1.基于现成模板进行编辑的模式这种模式下,模板是最为首要的,用户首先选择一个最为接近需求的模板,然后采用编辑.配置的方式对模板的名字.标题.栏目名称/数量.图片等进行修改.优点:简单快捷,如果图片素材等提前准备到位了,通过模板编辑配置的模式开发微信小程序,一般1.2个小时就能搞定!缺点:1)找到匹配度足够满意的模板并不容易:这种模式比较依赖于模板供应方的模板库丰富程度,一般来说,最终用户的需求都是千变万化的,往往都是各有各的诉求,即便模板

Android 设计模式之 浅谈MVP

一.概述 MVP(Model-View-Presenter) 是总所周知MVC模式的一个演变,他们的主要目的都是划分模块职责,降低模块耦合,易测试,提高代码复用,这里主要针对Android平台来简单分析MVP. 1.层级责任 Model:       负责数据的检索,持久化等操作 View:         负责UI的绘制和用户的交互 Presenter: 作为Model和View的中间协调部分,负责两者之间的业务逻辑处理 2.与MVC模式的区别 MVP模式与MVC模式从层级数据流向上来说一个主

浅谈移动应用的跨平台开发工具(Xamarin和React Native)

谈移动应用的跨平台开发不能不提HTML5,PhoneGap和Sencha等平台一直致力于使用HTML5技术来开发跨平台的移动应用,现在看来这个方向基本算是失败的,基于HTML5的移动应用在用户体验上与原生应用仍然存在着明显的差距. 与上述HTML5平台不同,Xamarin和React Native通过各自的方式来实现跨平台.Xamarin基于Mono框架将C#代码编译为原生平台代码,React Native则是在UI主线程之外运行一个JavaScript线程,两者呈现给用户的都是原生体验. 笔者

Android 应用层开发 Drawable 的一些叨叨絮

1 背景 博客也该开张了,懒惰都是惯的.既然这样,那就拿一个简单问题来叨叨絮吧:故事的起因是这样的,群里有一哥们仿写别人自定义控件,没整明白 Drawable 咋回事,然后群里炸开了锅,为了维护群里的世界和平,随决定叨叨絮一下 Android Drawable.关于 Android Drawable 可绘制对象资源的介绍大家可以去看看官方文档即可:而关于 Drawable 的使用细节其实你在 Drawable.java 的开篇大段注释中可以找寻到秘笈,所以说,如果你想玩转 Android 自定义

Android开发:浅谈MVP模式应用与内存泄漏

最近博主开始在项目中实践MVP模式,却意外发现内存泄漏比较严重,但却很少人谈到这个问题,促使了本文的发布,本文假设读者已了解MVP架构. 本文原创作者:xiong_it,链接:http://blog.csdn.net/xiong_it MVP简介 M-Modle,数据,逻辑操作层,数据获取,数据持久化保存.比如网络操作,数据库操作 V-View,界面展示层,Android中的具体体现为Activity,Fragment P-Presenter,中介者,连接Modle,View层,同时持有modl

浅谈MVP架构及开发模式

Model-View-Presenter(MVP)概述    MVC模式已经出现了几十年了,在GUI领域已经得到了广泛的应用,由于微软ASP.NET MVC Framework的出现,致使MVC一度成为.NET社区的热名话题.作为MVC的变种MVP模式,也已经出现好几年了,在微软模式与实践小组提供的Web Client Software Factory中,给出了实现MVP模式的应用程序最佳实践,本文将试着对这两种实现比较一二.MVC(Model-View-Controller,模型-视图-控制器

浅谈百度地图的简单开发之结合方向传感器实现定位功能(三)

  今天我们来谈下百度地图的定位功能.在此之前我已经将百度地图的基本地图大概说了下,事实上百度地图的基本功能还有非常多的内容. 感兴趣的能够到百度地图的开发人员的官网看看.今天就開始来讲下百度地图中的定位功能. 今天所讲的百度地图所涉及的内容主要有:基本定位的实现.自己定义定位图标.结合方向传感器定位,选择定位中的几种模式(罗盘模式,普通模式,尾随模式). 一.基本定位的实现: 所谓定位无非就是获取到一个地方所处地球的经纬度坐标.这个反映到地图中就是一个点.可是怎么去实现一个定位呢?? 首先,须