首次写博客,在写此文前页看了很多关于MVP的博文介绍,诸如:
- http://blog.youkuaiyun.com/lmj623565791/article/details/46596109
- http://blog.youkuaiyun.com/bboyfeiyu/article/details/46116335
- http://konmik.github.io/introduction-to-model-view-presenter-on-android.html
- http://zhengxiaopeng.com/2015/02/06/Android%E4%B8%AD%E7%9A%84MVP/
- https://github.com/antoniolg/androidmvp
- http://magenic.com/Blog/Post/6/An-MVP-Pattern-for-Android
下面谈谈个人的见解结合实例加以说明:
一、作为Android开发者,对于MVC、MVVM等都熟知一二,本文单独介绍一种MVC的衍生版本MVP。
大多人只听过MVP,实际开发却不知如何下手。而看过MVP结构的猿类们眼前一亮,我艹,结构清晰逻辑明确,但自己写的时候却又毫无头绪。
MVP作为MVC的衍生版,通过下图看看其有何区别:
①: 明显看出MVC中View和Control是可以互相交互,一个Activity可作为一个Control,一旦业务逻辑繁琐,迭代维护更新后,Activity越来越庞大,代码结构越来越混乱不利于维护开发。
②:MVP中,没有了Control,变成了Present,Present的可与View进行交互显示界面,而业务逻辑则将其全部封装在Present,或许大家问v和p怎么交互呢,当然是用接口实现。
关于data-view之间的交互可以看此文;
说再多不如实战演练,我们将以一个用户注册的简历例子来加以说明。
效果图如下:
项目结构图:
OK,要以MVP为整体设计,什么都不想,先将View接口和Present写出来,我们先完成View部分的设计:
package com.allure.mvp.view;
import com.allure.mvp.bean.RegisterBean;
/**
* Created by Allure on 15/7/31.
*/
public interface RegisterView {
String getNumber();
String getPassword();
String getVerCode();
void showSuccess(RegisterBean registerBean);
void showFailed();
}
View可知,我们注册用户,需要注册号,注册密码以及注册时候需要的验证码(假设需要),业务上肯定有注册开始,注册成功,注册失败,注册结束。。当然注册中你也可以写,具体看业务。简单吧,View的设计就这样完成了。
Present部分:
Present中,无非就注册的逻辑处理等,结果中处理View的显示和逻辑等。
package com.allure.mvp.present;
import android.os.Handler;
import com.allure.mvp.bean.RegisterBean;
import com.allure.mvp.impl.OnRegisterListener;
import com.allure.mvp.manager.UserManager;
import com.allure.mvp.view.RegisterView;
import java.util.HashMap;
import java.util.Map;
/**
* Created by Allure on 15/7/31.
*/
public class RegisterPresent {
private RegisterView registerView;
private Handler handler = new Handler();
public RegisterPresent(RegisterView registerView) {
this.registerView = registerView;
}
private Map<String,String> registerMapList() {
Map<String, String> ps = new HashMap<String, String>();
ps.put("userNumber", registerView.getNumber());
ps.put("userPassword", registerView.getPassword());
ps.put("verCode", registerView.getVerCode());
return ps;
}
/**
* 注册
*/
public void register() {
new UserManager().userRegister(registerMapList(), new OnRegisterListener() {
@Override
public void registerSuccess(final RegisterBean registerBean) {
//更新界面显示
handler.post(new Runnable() {
@Override
public void run() {
registerView.showSuccess(registerBean);
}
});
//后续逻辑等......
}
@Override
public void registerFailed() {
handler.post(new Runnable() {
@Override
public void run() {
registerView.showFailed();
}
});
}
});
}
}
注册逻辑有了,注册结果呢?OK设计注册回调接口OnRegisterListener
public interface OnRegisterListener {
void registerSuccess(RegisterBean registerBean);
void registerFailed();
}
上图代码可知有一个UserManager管理类,个人理解register属于用户体系的一部分,因此可将所有用户的login,register等业务方法均放入此类。这里简单说下如果业务需求特殊可将逻辑部分也接口化,具体看此文;
他即将业务逻辑也接口化了,个人觉得没有必要,当然这就仁者见仁智者见智了。
public class UserManager {
public void userRegister(final Map<String, String> stringStringMap, final OnRegisterListener registerListener) {
new Thread()
{
@Override
public void run()
{
try
{
Thread.sleep(2500);
} catch (InterruptedException e)
{
e.printStackTrace();
}
//模拟注册
if ("123".equals(stringStringMap.get("userNumber")) &&
"123".equals(stringStringMap.get("userPassword"))
&& "123".equals(stringStringMap.get("verCode"))
) {
RegisterBean registerBean=new RegisterBean();
registerBean.setUserNumber("123");
registerBean.setPassWord("123");
registerBean.setVerCode("123");
registerListener.registerSuccess(registerBean);
} else {
registerListener.registerFailed();
}
}
}.start();
}
}
UserManager的注册中,如果真是项目其他业务将会有返回值,此时简历Bean类,存入具体的数据。(此处模拟了一个用户注册)
public class RegisterBean implements Parcelable {
private String userNumber;
private String passWord;
private String verCode;
public String getVerCode() {
return verCode;
}
public void setVerCode(String verCode) {
this.verCode = verCode;
}
public String getUserNumber() {
return userNumber;
}
public void setUserNumber(String userNumber) {
this.userNumber = userNumber;
}
public String getPassWord() {
return passWord;
}
public void setPassWord(String passWord) {
this.passWord = passWord;
}
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(this.userNumber);
dest.writeString(this.passWord);
dest.writeString(this.verCode);
}
public RegisterBean() {
}
protected RegisterBean(Parcel in) {
this.userNumber = in.readString();
this.passWord = in.readString();
this.verCode = in.readString();
}
public static final Parcelable.Creator<RegisterBean> CREATOR = new Parcelable.Creator<RegisterBean>() {
public RegisterBean createFromParcel(Parcel source) {
return new RegisterBean(source);
}
public RegisterBean[] newArray(int size) {
return new RegisterBean[size];
}
};
}
至此,我们的MVP设计告一段落,什么少了Activity,Activity也就一个View,来负责各种UI等。上代码:
public class MainActivity extends Activity implements RegisterView {
private RegisterPresent registerPresent;
private EditText etUserNumber;
private EditText etPassWord;
private EditText etVercode;
private Button btRegister;
private ProgressBar progressBar;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
registerPresent=new RegisterPresent(this);
progressBar= (ProgressBar) findViewById(R.id.progressbar);
etUserNumber= (EditText) findViewById(R.id.et_usernumber);
etVercode= (EditText) findViewById(R.id.et_vercode);
etPassWord= (EditText) findViewById(R.id.et_password);
btRegister= (Button) findViewById(R.id.btn_register);
btRegister.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
progressBar.setVisibility(View.VISIBLE);
registerPresent.register();
}
});
}
@Override
public String getNumber() {
return etUserNumber.getText().toString();
}
@Override
public String getPassword() {
return etPassWord.getText().toString();
}
@Override
public String getVerCode() {
return etVercode.getText().toString();
}
@Override
public void showSuccess(RegisterBean registerBean) {
progressBar.setVisibility(View.GONE);
Toast1.showShort(MainActivity.this, registerBean.getPassWord() + "注册成功");
}
@Override
public void showFailed() {
progressBar.setVisibility(View.GONE);
Toast1.showShort(MainActivity.this, "注册失败哟!!!!!");
}
}
OK,MVP的开发到底为止。