Android程序结构--MVP模式

来源:互联网 发布:开淘宝网 编辑:程序博客网 时间:2024/06/01 07:36

一.前言

最近一直在研究一些关于架构的东西,lz是那种有强迫症的人,就是对于解耦有非常大的渴望,我理想中的架构是每一层各有各的工作,互不干扰。由于lz是学了javaWeb以后开始转到Android,在学习过程中也接触过各种语言和成熟的项目,所以之前一直都是沿用MVC这种代码结构,一直觉得挺好用的。
但是,在Android中,可能如果是简单的小项目,MVC确实很直接暴力,而且很容易入门,就是那种想要什么就拿什么的状态。可是当你的项目涉及的功能越多,在一个Activity中,要做的事也就越多,使用MVC结构的项目的代码非常非常丑,而且非常冗余

二.MVP与MVC的分析

传统的MVC结构
MVC结构我们肯定有接触,在MVC结构中,Activity代表Control,Layout就是View层,然后各种驱动器就是Model层。
在Activity中有时会做很多ui相关的逻辑,然后当要展示新的数据给用户看的时候,就要调用Model层的驱动器来获取数据,所以在MVC的结构中,Activity占据了重量级的位置
缺点:
当遇到一个Activity中涉及到多个功能模块的时候,不方便进行单个模块的调试,而且业务逻辑很难脱离出来。

MVP模式
MVP模式就是MVC的加强版,在MVP中,Activity作为View层,而不再是Control,这就意味这Activity只负责ui的处理,就好比说dialog的展示和各种按键的监听。那关于数据的处理和分发就落到了Presenter的身上,Presenter的任务就是告诉ui层要做什么事,Presenter还负责从Model获取数据,然后对数据进行二次加工处理然后展示到ui层,在这里View和Model就是完全脱离的,没有一点耦合。
lz从最近的俩个项目都是开始使用MVP模式,总结出来MVP有这几个明显的优点:

  1. view层完全脱离model层,所以重用性非常好和维护成本降低
  2. view层的逻辑由Presenter控制,所以对于那些只展示数据的view,有时可以多个view适配一个Presenter
  3. view层和presenter抽取接口,所以对于各个模块做了什么事都显得清晰可见

三.Demo

下面就是lz同一个项目的包结构对比
传统的mvc模式
这里写图片描述
mvp模式
这里写图片描述
在mvp模式有很明显的分层,model与view的交流通过presenter来完成,在看看其中一个view(登录):

/** * Created by 12262 on 2016/5/17. * 登录页面的方法 */public interface LoginView {    /**     * 弹出一个错误提示对话框     * @param content     */    void showErrorDialog(String content);    /**     * 弹出一个加载中的对话框     */    void showLoadingDialog();    /**     * 隐藏加载对话框     */    void hideLoadingDialog();    /**     * 跳到主页面     */    void runMainAct();}

上面的代码就包含了presenter控制view的方法,presenter通过构造函数传入的view,从而实现view的逻辑控制,下面看看Presenter:

/** * Created by 12262 on 2016/5/17. * 登录页面的大脑 */public interface LoginPre {    void login(String username,String password);}

是的你没看错,只需要一个方法就够了,也就是在Activity中创建一个presenter的实例,然后Activty监听登录按钮(ui的监听都属于view层的工作),然后调用LoginPre.login,在LoginPre中存在Activity的抽取接口类,只需要调用接口类中的方法即可实现对view层的控制,下面是presenter的实现类:

/** * Created by 12262 on 2016/5/17. * 登录页面大脑的实现类 */public class LoginPreImpl implements LoginPre {    //Model层实现类    OfficeModel model;    LoginView view;    public LoginPreImpl(LoginView view) {        this.view = view;        model = new OfficeModelImpl();    }    @Override    public void login(String username, String password) {        view.showLoadingDialog();        model.Login(username, password)                .subscribeOn(Schedulers.io())                .observeOn(AndroidSchedulers.mainThread())                .subscribe(new Observer<Html_Main>() {                    @Override                    public void onCompleted() {                        view.hideLoadingDialog();                    }                    @Override                    public void onError(Throwable e) {                            view.showErrorDialog(((MyException) e).getViewErrorInfo());                    }                    @Override                    public void onNext(Html_Main html_main) {                        //全局化数据                        Glo.html_main = html_main;                        ConstantValue.isOfficeLogin = true;                        view.runMainAct();                    }                })        ;    }    public void catchError(Throwable e) {    }}

就这样在MVP模式中完成一个操作,多么优美的结构。

MVP另外一个优点->更方便单元测试
对于大型或者功能较多的项目来说,测试某一个模块的功能是否能完成工作是一个很重要的点,在MVP模式中,由于层与层的分离,你完完全全可以取出一个模块来进行测试,例如现在我想测试登录功能:

public class ApplicationTest extends ApplicationTestCase<Application> {    public ApplicationTest() {        super(Application.class);    }    public void testLibLogin(){        OfficeModel model = new OfficeModelImpl();        //RxJava        model.Login("username","password")                .subscribe(new Observer<Html_Main>() {                    @Override                    public void onCompleted() {                    }                    @Override                    public void onError(Throwable e) {                        //登录失败,检查错误原因                    }                    @Override                    public void onNext(Html_Main html_main) {                        //登录成功                    }                });    }}
0 0
原创粉丝点击