您的位置:首页 > 运维架构 > 网站架构

MVP模式重用性的一些思考

2017-01-18 18:09 323 查看
一,概述



如上图看起来很好理解,其中View中包含了Presenter,Presenter中有View的接口和Model,可以调用View和Model。Model可以说完全独立。MVP与MVC的区别:在MVP中View并不直接使用Model,它们之间的通信是通过Presenter 来进行的,所有的业务逻辑都在Presenter,而在MVC中View会直接从Model中读取数据而不是通过 Controller。

MVP优点:

1、对MVC进一步解耦,model与view完全分离

2、单元测试,因逻辑都在Presenter,presenter的逻辑就可以方便单元测试,还有Model也很好测试

3、重用性,我们可以把Presenter用于不同的view上,还有Model更加可以独立使用

二,示例

下面模式是参考google的todoapp mvp示例

1,接口封装

package com.jerrycai.mymvp.login;

import com.jerrycai.mymvp.base.IView;
import com.jerrycai.mymvp.bean.User;

/**
* Created by JerryCai on 2017/1/18.
*/

public interface LoginContract {

interface View extends IView {

void loginSuccess(User user);

void loginFailure(String code, String msg);

}

interface Presenter {

void login(String phone, String pwd);

}
}


2,Model

package com.jerrycai.mymvp.service;

import com.jerrycai.mymvp.callback.Callback;

/**
* Created by JerryCai on 2017/1/18.
*/

public class UserService {
public void login(String phone, String pwd, Callback callback) {
//连网处理
}
}


3,View

package com.jerrycai.mymvp.login;

import android.app.Activity;
import android.os.Bundle;

import com.jerrycai.mymvp.bean.User;

/**
* Created by JerryCai on 2017/1/18.
*/

public class LoginActivity extends Activity implements LoginContract.View {
private LoginContract.Presenter mPresenter;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mPresenter = new LoginPresenter(this);
mPresenter.login("test","test");
}

@Override
public void loginSuccess(User user) {
//成功处理
}

@Override
public void loginFailure(String code, String msg) {
//失败处理
}
}


4,Presenter

package com.jerrycai.mymvp.login;

import com.jerrycai.mymvp.base.BasePresenter;
import com.jerrycai.mymvp.bean.User;
import com.jerrycai.mymvp.callback.Callback;
import com.jerrycai.mymvp.service.UserService;

/**
* Created by JerryCai on 2017/1/18.
*/

public class LoginPresenter extends BasePresenter<UserService, LoginContract.View> implements LoginContract.Presenter {

public LoginPresenter(LoginContract.View view) {
super(new UserService(), view);
}

@Override
public void login(String phone, String pwd) {
mMoudel.login(phone, pwd, new Callback<User>() {
@Override
public void onSuccess(User user) {
mView.loginSuccess(user);
}

@Override
public void Failure(String code, String msg) {
mView.loginFailure(code, msg);
}
});
}
}


三,一些思考

现在要加多一个功能,手机登录当然要获取验证码,而找回密码也要获取手机验证码,一般会写成同一个接口不同参数,这样我们的Model,View和Presenter怎么处理呢。

我看过不少人会Presenter是和界面挂钩,其中包括我以前也这样。若他们分工是A做登录,B做找回密码,他们可能会弄了一个LoginPresenter(有获取验证码的处理和有登录的处理)和一个ForgotPwdPresenter(有获取验证码的处理和有提交找回密码的处理),相应的View实现的功能也会实现一套一样的,Model估计倒不会再加一个。这样重用性明显少了点,model可以重用,presenter却不能重用了。那我们的Presenter不能和界面挂钩应该和model挂钩才对,一个界面应该允许多个不同功能逻辑的presenter,View可以实现多个View接口。下面上代码:

1,VerificationCodeContract

package com.jerrycai.mymvp.contract;

import com.jerrycai.mymvp.base.IView;

/**
* Created by JerryCai on 2017/1/18.
*/

public interface VerificationCodeContract {
interface View extends IView {

void onCodeCallback(boolean success, String errorMsg);

}

interface Presenter {

void getCode(String phone, int type);

}
}


2,VerificationCodeService

package com.jerrycai.mymvp.service;

import com.jerrycai.mymvp.callback.Callback;

/**
* Created by JerryCai on 2017/1/18.
*/

public class VerificationCodeService {
public void getCode(String phone, int type, Callback callback) {
//连网处理
}
}


3,VerificationCodePresenter

package com.jerrycai.mymvp.presenter;

import com.jerrycai.mymvp.base.BasePresenter;
import com.jerrycai.mymvp.callback.Callback;
import com.jerrycai.mymvp.contract.VerificationCodeContract;
import com.jerrycai.mymvp.service.VerificationCodeService;

/**
* Created by JerryCai on 2017/1/18.
*/

public class VerificationCodePresenter extends BasePresenter<VerificationCodeService, VerificationCodeContract.View> implements VerificationCodeContract.Presenter {
public VerificationCodePresenter(VerificationCodeContract.View view) {
super(new VerificationCodeService(), view);
}

@Override
public void getCode(String phone, int type) {
mMoudel.getCode(phone, type, new Callback() {
@Override
public void onSuccess(Object o) {
mView.onCodeCallback(true, null);
}

@Override
public void Failure(String code, String msg) {
mView.onCodeCallback(false, msg);
}
});
}
}


4,LoginActivity

package com.jerrycai.mymvp.login;

import android.app.Activity;
import android.os.Bundle;

import com.jerrycai.mymvp.bean.User;
import com.jerrycai.mymvp.contract.LoginContract;
import com.jerrycai.mymvp.contract.VerificationCodeContract;
import com.jerrycai.mymvp.presenter.LoginPresenter;
import com.jerrycai.mymvp.presenter.VerificationCodePresenter;

/**
* Created by JerryCai on 2017/1/18.
*/

public class LoginActivity extends Activity implements LoginContract.View,VerificationCodeContract.View {
private LoginContract.Presenter mPresenter;
private VerificationCodeContract.Presenter mCodePresenter;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//-------------示范用的,直接写在这样而已
mPresenter = new LoginPresenter(this);
mPresenter.login("test","test");

mCodePresenter = new VerificationCodePresenter(this);
mCodePresenter.getCode("test",0);
}

@Override
public void loginSuccess(User user) {
//成功处理
}

@Override
public void loginFailure(String code, String msg) {
//失败处理
}

@Override
public void onCodeCallback(boolean success, String errorMsg) {
//处理验证码
}
}


这样LoginPresenter和VerificationCodePresenter都可以重用,用在不同的东西,还有service肯定也可以的,也便于单元测试
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  mvp android 架构