SimpleNews- Android MVP模式学习
Posted 袁阳的csdn博客
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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架构实现。我的这篇文章就是在这个项目上展开的。
项目介绍
项目结构
整个项目的代码结构如图:
整个项目包括四个模块:Images,main,news,weather。每个模块下的结构为:
代码分析:
通过以上图片,我们可以发现:每个木块下面分成四个子目录:
model:存放所有的模型,以及与这些模型相关的操作抽象。这些模型进行面向对象编程,暴露出存取模型的方法供外界调用。
presenter:存放业务代码的抽象,以及实现。业务代码都在这里处理。
view:存放与界面相关操作的抽象。
widget:存放Android界面组件,Activity,Fragment。
代码总结如下:
- 几乎每一层都抽象出相关的操作,使每个模块充分解耦。
- 在view下抽象出与界面相关的操作,然后让Activity或者Fragment继承这些抽象。
- 在model抽象出存取数据的方法,并用相关类去实现。
- 在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模式的优点:
- 各个模块耦合降低。
- 单个类的职责更加明显。
- 代码短小,易于调试及维护。
至此介绍完了此项目的MVP模式,不知道各位看官理解的怎么样?下面用一张我自己总结的图来加深理解:
对于MVP模式的一些想法
- 由于没有统一的标准,只有大概的指导方向,可能十个采用MVP架构的项目对MVP的运用都不尽相同。有的人倾向于把所有的业务代码都移到Presenter中去,还有一部分只是将网络请求,json解析这一块移动过去,所以一千个读者,一千个哈姆雷特。我想:提供一种标准的MVP指导方案很有意义。
- 不是每个项目都要采用MVP来架构。MVP架构对于上规模的项目来说,可以很好的解耦和,便于团队开发以及未来的管理和维护。但是对于小型项目来说,却不是那么合适。因为:MVP项目会带来很多抽象类,让原本很简单的功能却需要代码的层层调用,这样就陷入了过度设计的怪圈。
- Google在2015年的IO大会上推出了data binding libarary。这个库可以使我们像在jsp中使用el表达式一样将Model与view绑定,在model变以后,视图会随之变化。这很有可能将Android的架构设计往MVVM推进,与现在的MVP架构比起来,我相信不管是官方还是开发者都会倾向于后者。
以上是关于SimpleNews- Android MVP模式学习的主要内容,如果未能解决你的问题,请参考以下文章
Android当中的MVP模式终篇---关于对MVP模式中代码臃肿