[置顶] SimpleNews- Android MVP模式学习

MVC模式与MVP模式

MVC模式是上世纪开始风靡的一种软件设计模式。尤其适用于Web开发。该模式将一个软件系统分成三个部分:控制层(Controller),显示层(View),模型层(Model)。每个层次各司其职,这样将原来的一个系统代码有机分成几个部分,便于出错控制和团队协作开发。总结一点就是:解决了原有系统的高度耦合。
MVP模式也是为了解耦和。有过Android开发经验的同学都知道,我们利用XML来画UI,然后在Java代码中找到控件,展示界面,有的时候我们还要在Activity里面写业务代码,这就导致了我们Activity类的代码冗长,职责不清晰,出错难于调试等等问题。虽然有的时候,我们也说这是MVC,但是与真正的MVC来比,V和C还是不够清晰,耦合度还是很高。渐渐地,有人提出了MVP模式。在去年中旬,在开发者头条上偶然看到一篇讲解MVP的文章,由于没有真实代码的演示,理论看着似懂非懂,再加上工作时间比较紧,就没有深入了解。今天也是偶然看到github上面一个项目,就是用MVP架构实现。我的这篇文章就是在这个项目上展开的。

项目地址:https://github.com/liuling07/SimpleNews

项目介绍

项目结构

整个项目的代码结构如图:

[置顶] SimpleNews- Android MVP模式学习_第1张图片

整个项目包括四个模块:Images,main,news,weather。每个模块下的结构为:

[置顶] SimpleNews- Android MVP模式学习_第2张图片

代码分析:

通过以上图片,我们可以发现:每个木块下面分成四个子目录:
model:存放所有的模型,以及与这些模型相关的操作抽象。这些模型进行面向对象编程,暴露出存取模型的方法供外界调用。
presenter:存放业务代码的抽象,以及实现。业务代码都在这里处理。
view:存放与界面相关操作的抽象。
widget:存放Android界面组件,Activity,Fragment。
代码总结如下:

  1. 几乎每一层都抽象出相关的操作,使每个模块充分解耦。
  2. 在view下抽象出与界面相关的操作,然后让Activity或者Fragment继承这些抽象。
  3. 在model抽象出存取数据的方法,并用相关类去实现。
  4. 在presenter中抽象出与界面无关的业务代码,并实现。在实现的时候,需要传入view的抽象以及model的抽象,以便业务逻辑的展开。

这样使得 数据,视图,逻辑分离。
下面,我拿一个具体的模块来说,就以images模块为例。
images模块的功能是从网络读取图片数据,解析数据成图片列表,然后使用RecyclerView以及CardView显示出这些图片。
下面我们先看其具体实现:
model层:
抽象出ImageModel。直接上代码:

package com.lauren.simplenews.images.model;

public interface ImageModel {
    void loadImageList(ImageModelImpl.OnLoadImageListListener listener);
}

这个方法是从网络获图片数据。然后通过ImageModelImpl来继承并实现这个接口。这里抽象除了为了与视图解耦和还有一个好处就是,我们对外提供一个统一的API,而不管内部的实现,不论我们是通过Volley,还是okHttp来获取数据,其他层次的代码不会变。

view层:

package com.lauren.simplenews.images.view;

import com.lauren.simplenews.beans.ImageBean;

import java.util.List;

public interface ImageView {
    void addImages(List<ImageBean> list);
    void showProgress();
    void hideProgress();
    void showLoadFailMsg();
}

这里抽象出了与界面相关的操作。然后,我们在ImageFragment中予以实现。实现的大致代码:

package com.lauren.simplenews.images.widget;

public class ImageFragment extends Fragment implements ImageView, SwipeRefreshLayout.OnRefreshListener {

    @Override
    public void addImages(List<ImageBean> list) {
     ...
    }

    @Override
    public void showProgress() {
        ....
    }

    @Override
    public void hideProgress() {
        ...
    }

    @Override
    public void showLoadFailMsg() {
        ...
    }
}

接下来就是关键的presenter层:

先抽象出业务方法:

package com.lauren.simplenews.images.presenter;

public interface ImagePresenter {
    void loadImageList();
}

接着,我们在其实现类中完成相关方法体的书写。

package com.lauren.simplenews.images.presenter;

public class ImagePresenterImpl implements ImagePresenter, ImageModelImpl.OnLoadImageListListener {

    private ImageModel mImageModel;
    private ImageView mImageView;

    public ImagePresenterImpl(ImageView imageView) {
        this.mImageModel = new ImageModelImpl();
        this.mImageView = imageView;
    }

    @Override
    public void loadImageList() {
        mImageView.showProgress();
        mImageModel.loadImageList(this);
    }

    @Override
    public void onSuccess(List<ImageBean> list) {
        mImageView.addImages(list);
        mImageView.hideProgress();
    }

    @Override
    public void onFailure(String msg, Exception e) {
        mImageView.hideProgress();
        mImageView.showLoadFailMsg();
    }
}

在ImagePresenterImpl中,通过传入的ImageView和ImageModel来完成业务代码。
这样,MVP模式就被运用到项目中。总结一下MVP模式的优点:

  1. 各个模块耦合降低。
  2. 单个类的职责更加明显。
  3. 代码短小,易于调试及维护。

至此介绍完了此项目的MVP模式,不知道各位看官理解的怎么样?下面用一张我自己总结的图来加深理解:
[置顶] SimpleNews- Android MVP模式学习_第3张图片

对于MVP模式的一些想法

  1. 由于没有统一的标准,只有大概的指导方向,可能十个采用MVP架构的项目对MVP的运用都不尽相同。有的人倾向于把所有的业务代码都移到Presenter中去,还有一部分只是将网络请求,json解析这一块移动过去,所以一千个读者,一千个哈姆雷特。我想:提供一种标准的MVP指导方案很有意义。
  2. 不是每个项目都要采用MVP来架构。MVP架构对于上规模的项目来说,可以很好的解耦和,便于团队开发以及未来的管理和维护。但是对于小型项目来说,却不是那么合适。因为:MVP项目会带来很多抽象类,让原本很简单的功能却需要代码的层层调用,这样就陷入了过度设计的怪圈。
  3. Google在2015年的IO大会上推出了data binding libarary。这个库可以使我们像在jsp中使用el表达式一样将Model与view绑定,在model变以后,视图会随之变化。这很有可能将Android的架构设计往MVVM推进,与现在的MVP架构比起来,我相信不管是官方还是开发者都会倾向于后者。

你可能感兴趣的:(android,mvc,mvp)