以前总是听说MVP模式,今天终于学习了一把
MVP 模式
是从经典的 MVC 模式演进而来,它们有相同的思想原理
Model:负责提供数据
View:负责展示
Controller/Presenter:负责逻辑的处理
MVC 模式结构:
Model:业务逻辑和实体模型
View:视图及布局文件
Controller:对应的是 Activity
MVP 模式结构:
Model:业务逻辑和实体模型
View:视图及布局文件
Presenter:负责完成 View 和 Model 之间的逻辑和交互
对比两种模式,发现 MVC 模式在Android有短板,Activity 充当的角色是 Controller,但在实际开发中处理View的逻辑。
View 会直接从 Model 中读取数据,而不是通过 Controller ,这样,View 中就会包含 Model 的信息,所以 MVC 中的角色
就会变得模糊不清。
在 MVP 模式中,View 和 Model 的交互式通过 Presenter 进行的,所有的交互都在 Presenter 内部。Activity 仅仅用于展示
界面和用户交互,这样就解决的 MVC 中角色不清的局面。
MVP 模式就相当于在 MVC 模式用添加了一个 Presenter 用于处理模型和逻辑,将 View 和 Model 完全独立开来,Activity 仅仅用于展示,
而不参与模型结构和逻辑
图示
小呆萌
用户进入Splash界面
* 判断网络是否存在(显示加载框)
* –存在:进入下一个页面
* –不存在:提示网络错误
* 最后隐藏加载框
分包:
--- model:
--- INetWork.java : Interface
--- Impl:
--- INetWorkImpl.java : Class
--- view:
--- ISplashView.java : Interface
--- SplashActivity implements ISplashView
--- presenter:
--- SplashPresenter.java : Class
View 层对应的是 SplashActivity ,它继承了所有 View 操作方法的接口 ISplashView
ISplashView.java
/**
* Created by sunxin on 2016/10/22.
* MVP模式中的View层
* 用户交互和视图显示,在android中对应activity
*
*
* 当用户进入Splash界面
* 判断网络是否存在:显示加载框
* --存在:进入下一个页面
* --不存在:提示网络错误
* 最后隐藏加载框
*/
public interface ISplashView {
/**
* 显示加载框
*/
void showLoadingDialog();
/**
* 进入下一个页面
*/
void enterNextActivity();
/**
* 提示网络错误
*/
void showNetWorkError();
/**
* 隐藏加载框
*/
void dismissDialog();
}
SplashActivity.java ,对每个操作进行了具体的实现
public class SplashActivity extends AppCompatActivity implements ISplashView{
SplashPresenter mSplashPresenter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mSplashPresenter = new SplashPresenter(this);
}
/**
* 在界面显示的时候处理逻辑
*/
@Override
protected void onResume() {
mSplashPresenter.doUILogic(this);
super.onResume();
}
/=============== ui具体展示 ===============/
@Override
public void showLoadingDialog() {
System.out.println("----------------showLoadingDialog------------------");
}
@Override
public void enterNextActivity() {
System.out.println("----------------enterNextActivity------------------");
}
@Override
public void showNetWorkError() {
System.out.println("----------------showNetWorkError------------------");
}
@Override
public void dismissDialog() {
System.out.println("----------------dismissDialog------------------");
}
}
Model 层 处理一些和数据相关的操作
INetWork.java
/**
* Created by sunxin on 2016/10/22.
* MVP中的model层
* 业务逻辑和实体模型
*/
public interface INetWork {
/**
* 判断网络是否可用
*/
boolean isNetWordAvailable(Context context);
}
INetWorkImpl.java
/**
* Created by sunxin on 2016/10/22.
* Model的实现类
*/
public class INetWorkImpl implements INetWork{
/**
* 判断网络是否可用,并返回
* @param context
* @return
*/
@Override
public boolean isNetWordAvailable(Context context) {
ConnectivityManager connectivityManager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
if (connectivityManager == null){
return false;
}else {
NetworkInfo networkInfo = connectivityManager.getActiveNetworkInfo();
if (networkInfo == null){
return false;
}else {
if (networkInfo.isAvailable()){
return true;
}
}
}
return false;
}
}
Presenter 层,负责界面逻辑和数据模型的处理
SplashPresenter.java
/**
* Created by sunxin on 2016/10/22.
* MVP模式中的P
* 负责完成View于Model间的逻辑和交互
*/
public class SplashPresenter {
//面向接口编程
INetWork mINetWork;
ISplashView mISplashView;
//在构造函数中初始化
public SplashPresenter( ISplashView ISplashView) {
mINetWork = new INetWorkImpl();
mISplashView = ISplashView;
}
/**
* 处理View和model之间的逻辑和交互
* @param context
*/
public void doUILogic(Context context){
/**
* 用户进入Splash界面
* 判断网络是否存在:显示加载框
* --存在:进入下一个页面
* --不存在:提示网络错误
* 最后隐藏加载框
*/
//显示加载框
mISplashView.showLoadingDialog();
//判断网络是否存在
if (mINetWork.isNetWordAvailable(context)){//网络可用
//存在,进入下一个界面
mISplashView.enterNextActivity();
}else {//网络不可用
//不存在,提示网络错误
mISplashView.showNetWorkError();
}
//隐藏加载框
mISplashView.dismissDialog();
}
}
总结
使用MVP模式会使得代码多出一些接口但是使得代码逻辑更加清晰,尤其是在处理复杂界面和逻辑时,我们可以对同一个activity将每一个业务都抽离成一个Presenter,这样代码既清晰逻辑明确又方便我们扩展。当然如果我们的业务逻辑本身就比较简单的话使用MVP模式就显得,没那么必要。所以我们不需要为了用它而用它,具体的还是要要业务需要。
参考: