什么是MVP?
现在,主流的android设计模式无非就是MVC,MVVM还有一个就是当下最流行的MVP模式,那么什么是MVP模式??
MVP模式是在MVC模式的基础上,针对MVC模式缺陷而设计的一种模式。在介绍MVP之前,很有必要先介绍一下MVC模式。按照MVC模式的分层,实体层Model、视图层View、控制层Controller。
可以清楚的看到MVC模式中的View可以直接与Model和Control进行交互,因此在大型的项目中,View层常常会有大量的代码,在后期的维护和管理中会有极大的不便,因此MVP模式诞生了。MVP也包括三层,Model、Presenter、和View层。核心思想就是把Activity中的UI逻辑抽象成View接口,把业务逻辑层抽象成Presenter接口,Model类还是原来的Model
** MVP如何使用
废话不多说,直接先上代码,这个是基于MVP实现注册登陆功能。
项目代码结构就是这样的:
、
可以看到每一层都有定义相对应的接口,虽然这样一来类会变的多一点,但是逻辑相对于MVC会更久清晰。首先介绍model层中的user和Iuser中的代码
==Iuse接口定义== 该接口的主要功能是实现提供user对外的接口
package com.reoger.grennlife.loginMVP.model;
/**
* Created by 24540 on 2016/9/10.
*/
public interface IUserModel {
String getName();
String getPassword();
int checkUserValidity(String name,String password);
}
==User类== 该类实现了检验用户的合法性的逻辑
package com.reoger.grennlife.loginMVP.model;
import android.util.Log;
/**
* Created by 24540 on 2016/9/10.
*/
public class UserMode implements IUserModel{
private String name;
private String password;
public UserMode(String name, String password) {
this.name = name;
this.password = password;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getPassword() {
return password;
}
@Override
public int checkUserValidity(String name, String password) {
if(name.equals(getName())&&password.equals(getPassword())){
Log.d("TAG","checkUserValidity "+ name+" mima"+password);
return 0;
}else
Log.d("TAG","132 checkUserValidity "+ name+" mima"+password);
return -1;
}
public void setPassword(String password) {
this.password = password;
}
}
至此,我们的model层就已经写完了,接下来就继续写Presenter中的代码
==ILoginPresenter接口定义== 该接口主要定义了登陆需要完成的逻辑代码
package com.reoger.grennlife.loginMVP.presenter;
/**
* Created by 24540 on 2016/9/10.
*/
public interface ILoginPresenter {
void clear();
void doLogin(String name,String password);
}
==LoginPresenterCompl类== 主要用于实现接口中方法的逻辑代码
package com.reoger.grennlife.loginMVP.presenter;
import android.util.Log;
import com.reoger.grennlife.loginMVP.model.IUserModel;
import com.reoger.grennlife.loginMVP.model.UserMode;
import com.reoger.grennlife.loginMVP.view.ILoginViw;
/**
* Created by 24540 on 2016/9/10.
*/
public class LoginPresenterCompl implements ILoginPresenter {
private ILoginViw mILoginView;
private IUserModel mIUserModel;
public LoginPresenterCompl(ILoginViw mILoginView) {
this.mILoginView = mILoginView;
mIUserModel = new UserMode("123","123");
Log.d("TAG",mIUserModel.getName());
}
@Override
public void clear() {
}
@Override
public void doLogin(String name, String password) {
Boolean isLoginSuccess = true;
final int code = mIUserModel.checkUserValidity(name,password);
if(code != 0){
isLoginSuccess = false;
}
Log.d("TAG",isLoginSuccess+" "+code);
final Boolean result = isLoginSuccess;
mILoginView.onLoginResult(result);
}
}
至此,Presenter中的代码就已经写完了,接下来,就是View层的代码了
==ILoginView接口== 用于定于View层需要实现的实现的方法的接口
package com.reoger.grennlife.loginMVP.view;
/**
* Created by 24540 on 2016/9/10.
*/
public interface ILoginViw {
void onClear();
void onLoginResult(Boolean result);
}
在这里,我们可以看到我们定义了两个方法,一个用于清楚输入的内容,一个用于接收prestern反馈的登陆结果。
==LongView类== 实现Activity的生命周期和对方法的调用
package com.reoger.grennlife.loginMVP.view;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.Toast;
import com.reoger.grennlife.R;
import com.reoger.grennlife.loginMVP.presenter.ILoginPresenter;
import com.reoger.grennlife.loginMVP.presenter.LoginPresenterCompl;
/**
* Created by 24540 on 2016/9/10.
*/
public class LoginView extends AppCompatActivity implements ILoginViw{
private ILoginPresenter mILoginPresenter;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.layout_text);
mILoginPresenter = new LoginPresenterCompl(this);
}
public void lalallal(View view){
mILoginPresenter.doLogin("123","123");
}
@Override
public void onClear() {
}
@Override
public void onLoginResult(Boolean result) {
if(result){
Toast.makeText(this,"login success",Toast.LENGTH_SHORT).show();
}else{
Toast.makeText(this,"login failed~!",Toast.LENGTH_SHORT).show();
}
}
}
至此,MVP的实现登陆功能的代码就全部写完了,可能看到采用MVC模式实现的代码会比较少,MVP的定义了比较多的接口,MVP显得比较复杂。但实际情况是,在实际项目中,基于MVP模式的的代码更加容易维护,下面介绍MVP模式的优点。
MVP的作用
- 分离了view和control,降低了耦合。
- activity只执行生命周期和方法的,代码更加简洁
- 接口化编程,方便进行单元测试,便于维护。
- 可以避免activity中可能存在的内存泄漏
MVP模式的实现
从上面的一张简单的MVp模式UML图,结合前面我们实现的代码,可以总结出:要使用MVp模式,至少要经历下面的步骤:
1. 创建IPresenter接口I,所有的业务逻辑接口都将放在这里,并创建他实现PresenterCompl
2. 创建IView接口,把所有的视图逻辑接口都放在这里,在activity或者Fragment中实现
3. Model并不是必须有的,但是一定会有View和Prestenter
4. 由 UML 图可以看出,Activity 里包含了一个 IPresenter,而 PresenterCompl 里又包含了一个 IView 并且依赖了 Model。Activity 里只保留对 IPresenter 的调用,其它工作全部留到 PresenterCompl 中实现
PS :通过前面的介绍,MVP模式在编写的的过程中可能会比基于MVC模式的代码更加复杂,刚开始使用MVP可能会觉得这么写法比较繁琐,而且效果不怎么理想。但在具体的项目中多写两次就能熟悉MVp模式的写法,理解MVp的真正的意义。