前言
刚开始学习mvp在android中使用的时候,我记得我是看了鸿洋大神的博客浅谈 MVP in Android
其实当时看了是蛮激动的,满心以为自己学会了mvp的设计,而且不管看谁的mvp介绍的博客,基本上都是一个样,让我深深的以为mvp就是想象的那么简单。当我真的在项目中使用的时候,我才发现mvp并不是那么简单,回过头再看鸿洋大神的博客的时候,才发现他讲的是真的如标题所说:浅谈,或者说真的只是一个入门级的Demo,更别说其他的博文都是copy来copy去,千篇一律.今天我不说mvp如何使用,因为我觉得自己不够格,我站在反方来提出问题
如果你看见了此篇博文,如果觉得可以有谈论的意思,那么在评论区和博主一起来讨论吧
首先偷懒盗用一张别人的mvp的图,这里面说明了三层之间的关系
P层同时有V层和M层的引用,而V层也有一个P层的引用,这里做一个解释
在平常的开发中,我们用mvp设计一个功能的时候,都是基本抛开实现不说,直接设计接口,什么意思呢,博主给大家举一个例子
登录案例
比如现在我们有一个登录的功能,那么我们假如只需要账号密码,那么现在外面普遍的做法是设计一个View接口,比如叫做ILoginView,代码如下
View
public interface ILoginView {
/** * 获取账号 * *@return */
String getAccount();
/** * 获取密码 * *@return */
String getPassword();
/** * 登陆成功,返回用户信息 *@param user */
void onLoginSuccess(User user);
/** * 登录失败 */
void onLoginFail();
}
我们可以看到,我们在设计的时候,不管是谁实现了这个View,都要实现这几个方法,一般是我们的Activity来实现这个View
来看看我们的Model
Model
public interface ILoginModel {
public void login(String account, String password,ILoginListen iLoginListen);
}
设计了一个登录的Model,最后一个参数是一个回调,因为登录一般都是异步的嘛
再来看看我们的P层
Presenter
public class LoginPresenter {
private ILoginView view;
private ILoginModel loginModel = new LoginModelImpl();
public LoginPresenter(ILoginView view) {
this.view = view;
}
/** * 执行登录 */
public void login(){
loginModel.login(view.getAccount(),view.getPassword(),new ILoginListen(){
@Override
public void loginSuccess(User user){
view.onLoginSuccess(user);
}
@Override
public void loginFail(Throwable throwable){
view.onLoginFail();
}
});
}
}
就如上面所说的关系一样,Presenter有View的引用,也有Model的引用,但是这里注意了,Presenter引用的View是通过构造方法传递进来的,而Model是直接创建Model的实现类就可以了
假如在任何一个界面想使用这个登录的功能,只需要拿到LoginPresenter就可以了,实例如下
public class MainAct extends AppCompatActivity implements ILoginView {
private LoginPresenter loginPresenter = new LoginPresenter(this);
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.act_main);
loginPresenter.login();
}
@Override
public String getAccount() {
return "xiaojinzi";
}
@Override
public String getPassword() {
return "qwe";
}
@Override
public void onLoginSuccess(User user) {
//
}
@Override
public void onLoginFail() {
//
}
}
在这个Activity中我们看到这个Activity对LoginPresenter有一个引用,所以这也是最上面的关系图中,View层为什么会有一个P的引用,基本上就是View层接口的实现类(Activity,Fragment)所引用的
上述的代码很简单,也是搜索出来基本千篇一律的文章中的介绍,这里博主将提出问题!
问题1
为什么上述例子中的用户名和密码参数需要通过View层的方法传递到Model层,
而不是在P层的login方法中写上对用的参数
比如下面的Presenter,如果你有话说,请在评论区留言!
public class LoginPresenter {
private ILoginView view;
private ILoginModel loginModel = new LoginModelImpl();
public LoginPresenter(ILoginView view) {
this.view = view;
}
/** * 执行登录 */
public void login(String account,String password){
loginModel.login(account,password,new ILoginListen(){
@Override
public void loginSuccess(User user){
view.onLoginSuccess(user);
}
@Override
public void loginFail(Throwable throwable){
view.onLoginFail();
}
});
}
}
问题2
假如有另一个功能设计的时候,也有登录的功能,但是账号和密码都不是界面上获取的
比如请求A成功以后返回账号和密码,然后再调用登录的接口去登录(这里只是一个假设)
理论上功能设计好了之后,应该是能复用最好了,那么如果Presenter2想拥有上面的登录的功能,就可以继承上面的LoginPresenter,但是你继承的时候会发现你需要实例化父类,并且需要一个ILoginView的接口
但其实你的界面并不需要ILoginView接口中的方法,但是你却不得不实现来使用登录功能
问题3
界面A有是登录功能,如上面所述
界面B验证账号功能,这时候你发现两个界面有其实有一样的方法String getAccount(),这时候你又会怎么办呢?是在A界面和B界面的View都写上一个String getAccount()方法,还是会怎么办呢?
暂时先提三个问题,有兴趣的童鞋在评论中和博主讨论吧!!