1. 对于 MVP 常常有许多人觉得,MVP 和 MVC 也没有什么区别啊。MVP 框架不过只是一个噱头吧。说实在的,刚接触 MVP 的那段时间,我也有同样的困惑。大家天天说的 MVP,怎么看上去和 MVC 那么像呢。除了代码变多了,怎么一点也看不到 MVP 有什么用,有什么区别。随着反复的理解 MVP 模式,看了大量网上所谓“牛人”写的各种 MVP(实际许多理解都不透彻),集百家之长,有一天,我读了一篇真正阿里云大牛的博客(链接不记得了)才真有醍醐灌顶的感觉。知道什么是 MVP。
2. 本文核心,一定不要把 P 层写成网络层,一定不要把 P 层写成 M 层,切记。P 层是写业务逻辑的,V 层是写视图控制逻辑的,M 层是管理数据的。
3. 下面以一个简单的 EvaluatingResultActivity 来说明其区别。当界面变得复杂时,更加需要重视这一块的区别。
一、View 层的视图控制代码与 P 层业务逻辑代码混合在一起。
界面的视图控制代码如下
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.article_activity_evaluating_result);
Toolbar toolbar = findViewById(R.id.toolbar);
initToolBar(toolbar);
mToolbarView.setLeftTitle("评测结果");
mToolbarView.setShareIcon(R.drawable.ic_share_black);
mHeaderView = findViewById(R.id.head_view);
tabLayout = findViewById(R.id.fea_aspirinTabLayout);
viewPager = findViewById(R.id.viewpager);
}
showLoadingView 的实现
...
showEmptyView 的实现
...
showContentView 的实现
...
界面初始化时的业务逻辑代码如下
if (mIsDemo) {
getEvalResultDemo(mEvalId);
} else {
getEvalResult(mEvalId);
}
逻辑1:界面刚打开时,需要缓解用户焦虑。(展示 loading)
mView.showLoadingView();
逻辑2:网络异常,取不到数据时需要通知用户。(展示 empty)
mView.showEmptyView();
逻辑3:数据正常时,需要展示到用户面前。(展示 content)
mView.showContentView();
界面初始化时的跨界面数据初始化代码如下
int evalId = getIntent().getIntExtra(ModuleArticle.EvaluatingResultActivity.EXTRA_INT_EVAL_ID, 0);
boolean isDemo = getIntent().getBooleanExtra(ModuleArticle.EvaluatingResultActivity.EXTRA_BOOLEAN_IS_DEMO, false);
int evalId = getIntent().getIntExtra(ModuleArticle.EvaluatingResultActivity.EXTRA_INT_EVAL_ID, 0);
boolean isDemo = getIntent().getBooleanExtra(ModuleArticle.EvaluatingResultActivity.EXTRA_BOOLEAN_IS_DEMO, false);
这里为啥需要写两遍,是因为可能 P 层和 V 层都需要。
有两个方式,一是写两遍,二是传值或者 V 层另外提供 get 方法。
旧的逻辑,View 层的视图控制代码 、P 层业务逻辑代码 、 跨界面数据初始化代码混合在一起
private int evalId;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.article_activity_evaluating_result);
Toolbar toolbar = findViewById(R.id.toolbar);
initToolBar(toolbar);
mToolbarView.setLeftTitle("评测结果");
mToolbarView.setShareIcon(R.drawable.ic_share_black);
mHeaderView = findViewById(R.id.head_view);
tabLayout = findViewById(R.id.fea_aspirinTabLayout);
viewPager = findViewById(R.id.viewpager);
evalId = getIntent().getIntExtra(ModuleArticle.EvaluatingResultActivity.EXTRA_INT_EVAL_ID, 0);
boolean isDemo = getIntent().getBooleanExtra(ModuleArticle.EvaluatingResultActivity.EXTRA_BOOLEAN_IS_DEMO, false);
showLoadingView();
if (isDemo) {
mPresenter.getEvalResultDemo();
} else {
mPresenter.getEvalResult(evalId);
}
}
新的逻辑,V层逻辑、P层逻辑及数据传递逻辑分离
新的 P 层
@Override
public void takeView(EvaluatingResultContract.View view) {
super.takeView(view);
mView.showLoadingView();
if (mIsDemo) {
getEvalResultDemo(mEvalId);
} else {
getEvalResult(mEvalId);