Android架构分析-MVC & MVP

原创 2017年11月14日 18:56:05

MVC的基本介绍

MVC全称是Model - View - Controller,是模型(model)-视图(view)-控制器(controller)的缩写。MVC是一种框架模式而非设计模式,GOF把MVC看作是3种设计模式:观察者模式、策略模式与组合模式的合体,而核心是观察者模式。简而言之,框架是大智慧,用来对软件设计进行分工;设计模式是小技巧,对具体问题提出解决方案,以提高代码复用率,降低耦合度。

使用 MVC,把业务逻辑抽离到 Controller 中,让 View 层专注于显示 UI。

MVC的优点

(1)首先就是理解比较容易,技术含量不高,这对开发和维护来说成本较低也易于维护与修改。

(2)耦合性不高,表现层与业务层分离各司其职,对开发来说很有利。

MVC的缺点

(1)完全理解MVC并不是很容易。使用MVC需要精心的计划,由于它的内部原理比较复杂,所以需要花费一些时间去思考。同时由于模型和视图要严格的分离,这样也给调试应用程序带来了一定的困难。每个构件在使用之前都需要经过彻底的测试。

(2)对于小项目,MVC反而会带来更大的工作量以及复杂性。

MVC在Android中的应用

Android中对MVC的应用很经典,在Android中视图View层一般采用XML文件进行界面的描述。

而对于模型Model部分则大多对应于本地的数据文件或网络获取的数据体,很多情况下我们对这些数据的处理也会在这一层中进行。

最后的控制器Controller则当之无愧的是右Activity承担。

MVP介绍

在Android中,业务逻辑和数据存取是紧紧耦合的,很多缺乏经验的开发者很可能会将各种各样的业务逻辑塞进某个Activity、Fragment或者自定义View中,这样会使得这些组件的单个类型臃肿不堪。如果不将具体的业务逻辑抽离出来,当UI变化时,你就需要去原来的View中抽离具体业务逻辑,这必然会很麻烦并且易出错。

MVP中把Layout布局和Activity作为View层,增加了Presenter,Presenter层与Model层进行业务的交互,完成后再与View层交互(也就是Activity)进行回调来刷新UI。这样一来,所有业务逻辑的工作都交给了Presenter中进行,使得View层与Model层的耦合度降低,Activity中的工作也进行了简化。但是在实际项目中,随着逻辑的复杂度越来越大,Activity臃肿的缺点仍然体现出来了,因为Activity中还是充满了大量与View层无关的代码,比如各种事件的处理派发,就如MVC中的那样View层和Controller代码耦合在一起无法自拔。

MVP模式是MVC模式的一个演化版本,MVP全称Model-View-Presenter。目前MVP在Android应用开发中越来越重要了。

(1)MVP模式会解除View与Model的耦合,有效的降低View的复杂性。同时又带来了良好的可扩展性、可测试性,保证系统的整洁性和灵活性。

(2)MVP模式可以分离显示层与逻辑层,它们之间通过接口进行通信,降低耦合。理想化的MVP模式可以实现同一份逻辑代码搭配不同的显示界面,因为它们之间并不依赖与具体,而是依赖于抽象。这使得Presenter可以运用于任何实现了View逻辑接口的UI,使之具有更广泛的适用性,保证了灵活度。

MVP模式的三个角色

(1)Presenter – 交互中间人:Presenter主要作为沟通View与Model的桥梁,它从Model层检索数据后,返回给View层,使得View与Model之间没有耦合,也将业务逻辑从View角色上抽离出来。

(2)View – 用户界面:View通常是指Activity、Fragment或者某个View控件,它含有一个Presenter成员变量。通常View需要实现一个逻辑接口,将View上的操作转交给Presenter进行实现,最后,Presenter 调用View逻辑接口将结果返回给View元素。

(3)Model – 数据的存取:Model 角色主要是提供数据的存取功能。Presenter 需要通过Model层存储、获取数据,Model就像一个数据仓库。更直白的说,Model是封装了数据库DAO或者网络获取数据的角色,或者两种数据方式获取的集合。

Android mvc mvp.png

MVP和MVC的对比

MVP架构:

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

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

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

MVC架构:

View可以与Model直接交互。

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

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

通过一个简单的例子来理解MVP模式

View层:

/**
  * ViewInterface
  * 定义一些通用的view接口
 */
public interface LoadDataView {
    /***
     * 耗时操作,加载数据,显示Progress
     */
    void showLoading();
    /***
     * 隐藏Progress
     */
    void hideLoading();
}

/**
 * 更细小的,用来显示图书细节的View接口
  */
public interface LoadBookView extends LoadDataView {
        void showDetailsView(BookEntity entity);
}

/***
 * Fragment,属于View层,实现了ViewInterface(LoadBookView)
 */
public class BookDetailFragment extends Fragment implements LoadBookView{
    /**图书条形码ISBN号*/
    public static final String ISBN = "9787121060748";
    /**持Presenter对象*/
    private BookDetailsPresenter presenter;

    @Override
    public void onActivityCreated(Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);
        initWidget();
        presenter = new BookDetailsPresenter(getActivity(), ISBN); // 实例化一个presenter对象
        presenter.setView(this); //让Presenter持一个ViewInterface实例(LoadBookView)
        presenter.loadData(); //告诉Presenter快给我加载Data
    }    

     @Override
    public void showDetailsView(BookEntity entity) {
        //更新UI等操作
    }

    @Override
    public void showLoading() {
        rlProgress.setVisibility(View.VISIBLE);
    }

    @Override
    public void hideLoading() {
        rlProgress.setVisibility(View.GONE);
    }
}

2、Presenter层:

public class BookDetailsPresenter {
    /**持一个Model层的对象,用来从网页接口Rest Api中提取数据*/
    private RestApi restApi = null;
    /**一个ViewInterface对象,用来回调Data给View*/
    private LoadBookView loadBookView;
    private String isbn;

    public BookDetailsPresenter(Context context, String isbn) {
        restApi = new RestApiImpl(context);
        this.isbn =isbn;
    }
    public void setView(LoadBookView loadBookView) {
        this.loadBookView = loadBookView;
    }
    public void loadData() {
        loadBookView.showLoading();
        //耗时操作,开个线程异步的加载数据
        Thread thread = new Thread(new Runnable() {
            @Override
            public void run() {
                restApi.getBookDetailByIsbn(isbn, bookDetailsCallback);
            }
        });
        thread.start();
    }
    //匿名内部类,接收bookDetailCallback的回调数据
    private RestApi.BookDetailsCallback bookDetailsCallback = new RestApi.BookDetailsCallback() {
        @Override
        public void onBookEntityLoaded(BookEntity bookEntity) {
            notifyDataLoadedSuccessful(bookEntity);
            BookDetailsPresenter.this.loadBookView.hideLoading();
        }

        @Override
        public void onError(Exception e) {
            //异常后的相关处理
        }
    };

    /***
    * 通知获取数据成功了,赶快通知UI更新吧
    */
    private void notifyDataLoadedSuccessful(final BookEntity bookEntity) {
        Handler handler = new Handler(Looper.getMainLooper());
        handler.post(new Runnable() {
            @Override
            public void run() {
                BookDetailsPresenter.this.loadBookView.showDetailsView(bookEntity);
            }
        });
    }  
}

3、Model层:

/***
* 整个应用程序需要的数据实体类
*/
public class BookEntity {
    //一些set,get方法
}

/**
 * 一个接口,用来从rest api api获得数据,它的实现在RestApiImpl中
 */
public interface RestApi {
    String API_ISBN_BASE_URL = "https://api.douban.com/v2/book/isbn/";
    /***
    * 更细小的接口,用来将获取到的数据,回调给它的调用者
    */
    interface BookDetailsCallback {
        void onBookEntityLoaded(BookEntity bookEntity);
        void onError(Exception e);
    }
    /**
     * 从网络获取数据,然后通过bookDetailCallback回调给Presenter
     * @param isbn
     * @param bookDetailsCallback
     */
    void getBookDetailByIsbn(final String isbn, final BookDetailsCallback bookDetailsCallback);

}
版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/u011808673/article/details/78511174

MVC、MVP、MVVM,谈谈我对Android应用架构的理解

今日科技快讯近日,美国国务院公布了一条新规,要求外国人在申请美国签证时提供过去5年在指定社交媒体平台上使用的用户名。据美国《纽约时报》报道,新规针对的指定社交媒体平台有20家,其中大部分设在美国,包括...
  • c10WTiybQ1Ye3
  • c10WTiybQ1Ye3
  • 2018-04-02 00:00:00
  • 100

android之MVP框架流程图,部分

  • 2017年11月17日 00:58
  • 39KB
  • 下载

浅谈Android中的MVC与MVP模式

使用MVC或者MVP模式会增加很多的类,但是确可以让代码结构变得清晰,方便了后期维护拓展方便。把数据层跟视图层分离,处理事务的逻辑单独的放在一个类中,让Activity仅仅具有展示功能。 下面我们就M...
  • a516972602
  • a516972602
  • 2016-05-10 11:45:10
  • 2490

android中的MVC,MVP和MVVM模式简单总结

1.MVC View:对应于xml布局文件 Model:实体模型 Controllor:对应于Activity业务逻辑,数据处理和UI处理 xml的view功能太过于弱化,导致actvity里面即处...
  • kaikevin01
  • kaikevin01
  • 2017-12-13 22:39:29
  • 161

细说Android框架设计三剑客MVC、MVP和MVVM

最近几年的移动端开发越来越火,功能越来越强大,处理业务越来越复杂,因此对系统扩展性的要求越来越高。而为了更好地进行移动端架构设计,我们最常用的就是MVC和MVP,今天本篇博客就和大家一起聊一聊这两种框...
  • mynameishuangshuai
  • mynameishuangshuai
  • 2016-10-14 11:44:41
  • 13448

两张图看懂Android开发中MVC与MVP的区别

看了很多文章,没有很好的文章能简明扼要的说清楚Android开发中MVC和MVP的区别。MVC很早就出来了,之前广泛用于JavaWeb开发中,MVC也可以用来开发Android,但是有些水土不服!1、...
  • u010072711
  • u010072711
  • 2017-08-13 02:06:23
  • 1420

MVC与MVP架构特点与区别-android

> MVC/MVP  View强依赖于Model是MVC的主要问题。由此导致很多控件都是根据业务定制,从Android的角度来看,原本可以由一个通用的layout就能实现的控件,由于要绑...
  • ShareUs
  • ShareUs
  • 2016-05-23 14:18:45
  • 31206

认清Android框架 MVC,MVP和MVVM

相信大家对MVC,MVP和MVVM都不陌生,作为三个最耳熟能详的Android框架,它们的应用可以是非常广泛的,但是对于一些新手来说,可能对于区分它们三个都有困难,更别说在实际的项目中应用了,有些时候...
  • jdsjlzx
  • jdsjlzx
  • 2016-04-17 18:15:56
  • 31223

Android----MVC、MVP、MVVM、区别介绍

相信大家对MVC,MVP和MVVM都不陌生,作为三个最耳熟能详的Android框架,它们的应用可以是非常广泛的,但是对于一些新手来说,可能对于区分它们三个都有困难,更别说在实际的项目中应用了,有些时候...
  • copy_yuan
  • copy_yuan
  • 2016-05-28 14:07:17
  • 4788

浅谈Android中MVP模式与MVC模式的区别

理论内容转载自:http://blog.csdn.net/lmj623565791/article/details/46596109一、概述对于MVP(Model View Presenter),大多...
  • uniquemei
  • uniquemei
  • 2016-06-27 18:01:41
  • 6564
收藏助手
不良信息举报
您举报文章:Android架构分析-MVC & MVP
举报原因:
原因补充:

(最多只允许输入30个字)