Sunxin'Blog

Android - MVP模式小试

MVP 模式与MVC模式

MVP模式是从经典的 MVC 模式演进而来,它们有相同的思想原理。

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 模式中,View 和 Model 的交互式通过 Presenter 进行的,所有的交互都在 Presenter 内部。Activity 仅仅用于展示界面和用户交互,这样就解决的 MVC 中角色不清的局面。

MVP模式小呆萌

用户进入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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
/**
* 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 ,对每个操作进行了具体的实现

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
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

1
2
3
4
5
6
7
8
9
10
11
12
/** 
* Created by sunxin on 2016/10/22.
* MVP中的model层
* 业务逻辑和实体模型
*/

public interface INetWork {
/**
* 判断网络是否可用
*/
boolean isNetWordAvailable(Context context);
}

INetWorkImpl.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
/**
* Created by sunxin on 2016/10/22.
* Model的实现类
*/

public class INetWorkImpl implements INetWork{
/**
* 判断网络是否可用,并返回
* @param context
* @return
*/
@Override
public boolean isNetWorkAvailable(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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
/**
* 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.isNetWorkAvailable(context)){//网络可用
//存在,进入下一个界面
mISplashView.enterNextActivity();
}else {//网络不可用
//不存在,提示网络错误
mISplashView.showNetWorkError();
}
//隐藏加载框
mISplashView.dismissDialog();
}
}

小结:

使用MVP模式会使得代码多出一些接口但是使得代码逻辑更加清晰,尤其是在处理复杂界面和逻辑时,
我们可以对同一个activity将每一个业务都抽离成一个Presenter,这样代码既清晰逻辑明确又方便我们扩展。
当然如果我们的业务逻辑本身就比较简单的话使用MVP模式就显得,没那么必要。所以我们不需要为了用它而用它,具体的还是要要业务需要

-------------本文结束感谢您的阅读-------------