Android程序结构--MVP模式

一.前言

最近一直在研究一些关于架构的东西,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) {
                        //登录成功
                    }
                });
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值