Android MVP模式

一、 定义

MVP从更早的MVC框架演变过来,与MVC有一定的相似性:Controller/Presenter负责逻辑的处理,Model提供数据,View负责显示。

已经有了MVC,为什么还要提出MVP?

在Android开发中,Activity并不是一个标准MVC模式中的Controller。按理说,Controller只需要接受用户的输入,然后与Model进行交互进行数据的更新。
这也正是问题所在。看过不少2000行+的Activity,真的想吐,这其中Activity担负着用户每个操作交互,庞大可以理解。但实际上Activity还同时处理着业务逻辑功能等,这是Controller不应该去做的事情,结果带来的是臃肿的Activity,可维护性低。

为了解决这个问题,引入了MVP框架。

二、 好处

1.View与Model并不直接进行交互,而是通过Presenter连接彼此。View中不存在Model,从而也不会存在业务逻辑;
2.Presenter与View的交互是通过接口来实现的,耦合度低,也有利于单元测试;
3.Presenter是基于行为的,一个Presenter可用于多个View,增强了代码复用。

三、 简单例子

我们现在来模拟一个界面,用户修改用户名。

这里写图片描述

先看看码完的demo包结构:
这里写图片描述
接下来,我们慢慢来解析MVP每一元素。

(一)、Model
往业务上看,User这个实体类必须得有,还必须要有相关的业务方法,更新userName。

public class User {
    private String userName;
    private String password;

    public String getUserName() {
        return userName;
    }

    public void setUserName(String userName) {
        this.userName = userName;
    }

    public String getPassword() {
        return password;
    }

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

    public void updateUserName(String username, OnUserNameUpdateListener listener);

}
public class UserNameUpdateBiz implements IUserNameUpdateBiz {

    @Override
    public void updateUserName(final String username, final OnUserNameUpdateListener listener) {
        // 模拟访问服务修改username
        new Thread() {
            @Override
            public void run() {
                try {
                    // 模拟耗时操作
                    sleep(1200);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                int resultCode = 1; // 这里假设访问网络修改成功
                if (resultCode == 1) {
                    User user = new User();
                    user.setUserName("cxy");
                    listener.updateSuccess(username);
                } else {
                    listener.updateError();
                }

            }
        }.start();
    }

}

这个业务很简单,在这里抽象出一个业务方法-updateUserName,并且付诸实现,这里做的是耗时操作,访问网络去修改userName。模拟了耗时操作,并使用了一个接口做网络返回状态的监听。

(二)、View

View与Model完全独立,在View中不会看到Model的身影,它们是通过Presenter进行交互的。而View与Presenter的交互方式是通过接口实现。在Android中,View的体现一般有Activity、Fragment、View等等。在UI层启动之后,实例化相应的Presenter。接下来先看下View与Presenter之间的接口IUserNameUpdateView:

public interface IUserNameUpdateView {

public void showLoading();

    public void hideLoading();

    public String getUserName();

    public void clearInput();

    public void showFailedError();

}

定义了这么多的方法,这都是要Activity具体去实现的方法,实现各式各样的交互,当然这些方法不包括任何逻辑。
终于迎来了View了,在MVP中,Activity就是View。

public class UserNameUpdateActivity extends Activity implements IUserNameUpdateView {

    private EditText mETUserName;
    private Button mBtnSure;
    private ProgressBar mPb;

    private UserNameUpdatePresenter mUserNameUpdatePresenter = new UserNameUpdatePresenter(this);

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_username_update);

        mETUserName = (EditText) findViewById(R.id.et_mobile);
        mBtnSure = (Button) findViewById(R.id.btn);
        mPb = (ProgressBar) findViewById(R.id.pb);

        mBtnSure.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                mUserNameUpdatePresenter.updateUserName();
            }
        });
    }

    @Override
    public void showLoading() {
        mPb.setVisibility(View.VISIBLE);
    }

    @Override
    public void hideLoading() {
        mPb.setVisibility(View.GONE);
    }

    @Override
    public String getUserName() {
        return mETUserName.getText().toString();
    }

    @Override
    public void clearInput() {
        mETUserName.setText("");
    }

    @Override
    public void showFailedError() {

    }
}

这里接口会引导Activity去做事,我们关键要知道的是接口的方法要如何定义,这里要根据具体的业务来了。

(三)、Presenter
既使View与Model完全隔离,又连接彼此,“又爱又恨”吶。

public class UserNameUpdatePresenter {

    private IUserNameUpdateBiz userNameUpdateBiz;
    private IUserNameUpdateView userNameUpdateView;

    public UserNameUpdatePresenter(IUserNameUpdateView userNameUpdateView) {
        this.userNameUpdateView = userNameUpdateView;
        this.userNameUpdateBiz = new UserNameUpdateBiz();
    }

    public void updateUserName() {
        userNameUpdateView.showLoading();
        userNameUpdateBiz.updateUserName(userNameUpdateView.getUserName(), new OnUserNameUpdateListener() {
            @Override
            public void updateSuccess(String userName) {
                // 存入本地user信息
//                UserConfig.updateNativeUserName(userName);
            }

            @Override
            public void updateError() {
                userNameUpdateView.showFailedError();
            }
        });
    }
}

既然连接Model与View,又实现抽象,所以有这二者的接口对象,在相关的业务方法中,具体是让Model去执行,View做对应的显示。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值