初识android设计模式—MVP

一、什么是MVP?

MVP是基于MVC提出来的,MVC模式在android开发中的体现不是特别的明显,尤其是当我们按照传统的写法,会在Activity和Fragment中写大量的业务逻辑和UI界面操作的代码,以至于Controller和View分隔的不是特别的明显。然而MVP的出现完美的解决了Activity/Fragment中业务逻辑和界面操作的耦合问题。简而言之,MVP的出现就是为了解耦,提高代码可维护性。

MVP中:Presenter在这里充当了MVC中Controller的角色,Model只能通过Presenter来通知View进行界面的更新。代码结构如下图所示:


Data Layer:非传统意义的 Model 层,包含 dto(Data Transfer Object)、service 和 model。其中 service 包含 Net和 Local 等不同服务,用于提供不同的数据服务。model 负责处理某个业务对象的业务逻辑,并通过 dto 或元数据 与 Presenter 层进行交互。

View Layer:视图层,包括各种activity,adapter,fragment,view。只关注与用户交互,以及视图操作(动画、界面输出、更新等)。

Presenter Layer:控制逻辑层。将控制逻辑从 Activity 中剥离并抽象成不同的Presenter。负责「View 与 Model 层之间的控制与交互」


废话不多说了,下面上一个简单的例子,体验一下MVP设计模式:

这里模拟一下用户登录的场景,输入账号和密码,后台请求验证账号密码是否正确,正确的话就直接登录成功。




首先看一下代码的层级结构:


这里我么的bean下面的就相当于我们model层下面封装好的数据实体,biz下面就是我们的登陆的业务逻辑,presenter下面负责View和Model之间的交互。

User实体类的代码:就两个参数,一个登陆账号,一个登陆密码

package com.guannan.mvpdemo.bean;

/**
 * Created by guannan on 2016/10/11.
 */

public class User {

    private String account;
    private String password;

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    public String getAccount() {
        return account;
    }

    public void setAccount(String account) {
        this.account = account;
    }
}

biz(业务逻辑层的代码),这里我们有一个登陆的需求所以我们提供一个登陆的接口IUserLogin,下面有一个login方法,假如我们有其他登陆相关的方法可以在这里面进行添加

package com.guannan.mvpdemo.biz;

/**
 * Created by guannan on 2016/10/11.
 */

public interface IUserLogin {

    public void login(String username,String password,OnLoginListener loginListener);
}

然后我们的OnLoginListener下面使我们登陆成功以后所回调的方法,这个接口作为我们和Presenter层的交互

package com.guannan.mvpdemo.biz;

import com.guannan.mvpdemo.bean.User;

/**
 * Created by guannan on 2016/10/11.
 */

public interface OnLoginListener {

    void loginSuccess(User user);   //登录成功
    void loginFaild();  //登录失败
}

最后的UserLogin实现IUserLogin完成我们整个登录的业务逻辑

package com.guannan.mvpdemo.biz;

import com.guannan.mvpdemo.bean.User;

/**
 * Created by guannan on 2016/10/11.
 */

public class UserLogin implements IUserLogin {

    @Override
    public void login(final String username, final String password, final OnLoginListener loginListener) {

        new Thread(new Runnable() {
            @Override
            public void run() {

                try {
                    Thread.sleep(2000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }

                if("zgn".equals(username) && "123".equals(password)){
                    User user=new User();
                    user.setAccount(username);
                    user.setPassword(password);
                    loginListener.loginSuccess(user);   //登录成功
                }else{
                    loginListener.loginFaild();     //登录失败
                }
            }
        }).start();
    }
}

这里重点看一个LoginPresenter所完成的操作,这里调用了UserLogin里面的login方法,并通过OnLoginListener的接口回调进行登录成功和失败的操作。

package com.guannan.mvpdemo.presenter;

import android.content.Intent;
import android.os.Handler;

import com.guannan.mvpdemo.SuccessActivity;
import com.guannan.mvpdemo.bean.User;
import com.guannan.mvpdemo.biz.IUserLogin;
import com.guannan.mvpdemo.biz.OnLoginListener;
import com.guannan.mvpdemo.biz.UserLogin;
import com.guannan.mvpdemo.view.ILoginView;

/**
 * Created by guannan on 2016/10/11.
 */

public class LoginPresenter {

    IUserLogin mIUserLogin;
    ILoginView mILoginView;
    private Handler mHandler=new Handler();
    public LoginPresenter(ILoginView iLoginView){

        this.mIUserLogin=new UserLogin();
        this.mILoginView=iLoginView;
    }

    public void login(){

        mIUserLogin.login(mILoginView.getUserName(), mILoginView.getPassword(), new OnLoginListener() {
            @Override
            public void loginSuccess(User user) {

                mHandler.post(new Runnable() {
                    @Override
                    public void run() {

                        mILoginView.clearPassword();
                        mILoginView.clearUsername();
                        Intent intent=new Intent(mILoginView.getActivity(), SuccessActivity.class);
                        mILoginView.getActivity().startActivity(intent);
                        mILoginView.getActivity().finish();
                    }
                });
            }

            @Override
            public void loginFaild() {

            }
        });
    }
}

另外我们登录成功或者失败后需要对View层的Activity的界面进行一些操作,这里提供了另外一个接口ILoginView,这里主要是LoginPresenter层对UI层的一些界面操作(获取账号getUsername(),获取密码getPassword(),清空账号clearUsername(),清空密码clearPassword())。

package com.guannan.mvpdemo.view;

import android.app.Activity;

/**
 * Created by guannan on 2016/10/11.
 */

public interface ILoginView {

    public String getUserName();
    public String getPassword();

    public void clearUsername();
    public void clearPassword();

    public Activity getActivity();

}

Presenter层和View层的交互就是通过接口回调的方式,Model层和Presenter层的交互可以通过接口回调的方式,当然也可以采用EventBus,otto等方式。这里不再介绍。


好久没写博客了,就写到这里,大神请飘过,欢迎吐槽~


参考资料:

https://zhuanlan.zhihu.com/p/20358928

https://www.zhihu.com/question/35185744

http://blog.csdn.net/lmj623565791/article/details/46596109

http://rocko.xyz/2015/02/06/Android%E4%B8%AD%E7%9A%84MVP/


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值