之前一直用谷歌的mvp模式,不过还是觉得m与p的耦合有点高,前段时间有人推荐给我一个新的mvp结构,其实也不新,只是我没用过而已。这里是它的连接地址:https://github.com/antoniolg/androidmvp
它和常用的mvp最大的区别在于她添加了 所谓的‘耦合因子’(这么说显得高端一些,其实就是个接口而已)用来进一步解耦M与P层,我们平日(个人这么用而已)用到的mvp中,与数据源有关的操作很多放在P的实现中,到最后会发现P层就是一整个的P+V的结合体,并没有很完美的诠释presenter的主持思想。为了解决这个问题,刚好又有人给了点建议(上文链接),索性更新,和团队讨论完后将用于实际开发。
先大体讲解上面链接项目的原理。直接贴上其中的一张图,一目了然。
来自网络
这是一个登录的mvp结构,很明显它多了个Interactor(耦合因子),用一句名言:存在即合理。这个耦合因子的存在是为了解决P层的数据源访问。P层将login请求转发给耦合因子,然后再通过耦合因子中的接口回调给P层,再由P层回调给V层。
LoginActivity —> LoginPresenter —> LoginInteractor—>LoginPresenter—>LoginActivity
LoginInteractor这到底是个什么东西,说白了就是一个接口,项目中是这样的:
public interface LoginInteractor {
interface OnLoginFinishedListener {
void onUsernameError();
void onPasswordError();
void onSuccess();
}
void login(String username, String password, OnLoginFinishedListener listener);
}
有接口就有实现,再看它的实现类 LoginInteractorImpl:
public class LoginInteractorImpl implements LoginInteractor {
@Override
public void login(final String username, final String password, final OnLoginFinishedListener listener) {
// Mock login. I'm creating a handler to delay the answer a couple of seconds
new Handler().postDelayed(new Runnable() {
@Override public void run() {
if (TextUtils.isEmpty(username)) {
listener.onUsernameError();
return;
}
if (TextUtils.isEmpty(password)) {
listener.onPasswordError();
return;
}
listener.onSuccess();
}
}, 2000);
}
}
那么在什么地方用呢?看下面
presenter=new LoginPresenterImpl(this,newLoginInteractorImpl());
在activity中,实例化Presenter的时候讲耦合因子的实现即new LoginInteractorImpl();作为行参传入。然后在Presenter中调用login()进行登陆请求。
大体流程就是这样,不详细的地方建议直接跑github上的demo。虽然很解耦,但是我发现按照那种方法我们新建的类会很多。
github的截图
如果一个登录就算用了mvp,还需要建这么多类,想想还是挺恐怖的。为此,我们可以结合契约模式进行简化一下。首先看简化后的类:
项目截图
Constract是引用自谷歌mvp中的结构,它所表达的就是将vp层中的接口进行统一的管理,即与LoginActivity签订契约(Constract)。说得这么神奇,其实也就一接口。
public interface LoginConstract {
interface LoginPresenter{
void login(String name, String passWord);
}
interface LoginView{
void showLoading();
void loginError(String message);
void loginSuccess();
}
//耦合因子,解耦presenter数据层
interface LoginInteractor{
interface LoginBackListener{
void loginSuccess();
void loginError(String message);
}
void login(String name, String passWord, LoginBackListener loginBackListener);
}
}
这样再结合刚开始的那个结构是不是更加清晰了。虽然我一直很随意的说这就是一个接口,但这其实是一种思想,一种基于业务的分解思想。我觉得这种思想是很值得学习与思考的。
上面的东西讲得都很浅,很多的代码也都没补全。我建议直接去github看源码,泡一泡,实践出真理。
基于这种结构,我自己封装了mvp+rxjava2+retrofit2的网络框架,可以看看,我想会对不太了解mvp或者还没开始用mvp的同学有所帮助。其中网络层的封装很多我是借鉴别人的思想与代码,不喜轻喷。最后奉上源码:
欢饮star我的github:https://github.com/Littlexs/rxjavaRetrofitMvp