最近看了些MVP的例子,谈谈自己的理解。水平不够,所以本文写的是一些理解的概念
我们设计的代码应该遵守单一职责原则,也就是一个类干一件事。而当View(Activity或Fragment、下文中的View都是指这俩货)和Model(即数据提供者)总是死缠烂打的纠结在一起,那代码看起来就会欲仙欲死。而MVP是一个用于强拆View与Model之间孽缘的有力工具。
开始接触鬼知道MVP是啥,管他三七二十一,先看看再说。这么多人推荐使用的MVP(Google推荐),总不会坑我,多学点东西也没坏处。
废话不多说,先上一张网上偷的图
图中有我们重点关注3个东西:
-
View
身份:Boss
职责:给用户提供交互界面,对用户的操作作出回应
简介:作为Boss,啥我都不管。交给我的管事Presenter就行了只要能体体面面的在外面装逼就行了。 -
Presenter
身份:管事
职责:给View办事的直系下属,所有View要办的事都交给他
简介:Boss的事儿太多啦,我一个人可忙不过来,找几个小弟(Model)来跑腿儿吧。我只需要把结果告诉Boss就行了。 -
Model
身份:小弟
职责:是Presenter的狗腿子,脏活累活都叫他干,干完还要通知Presenter结果。
简介:之前MVC的时候,我还能跟BOSS说上几句话,现在彻底没戏了。f**k,活儿都我干,功劳全让那老家伙得去了。
上面是MVP主要的管理结构。当然,Model、View、Presenter之间还可以有些别的角色,好让整个管理机构更加完善。毕竟,公司越大,角色就越多。比如图中Model与Presenter之间,Presenter指向Model的时候,并没有直接指向View,而是指向一个圆圈。这个表示,Boss是很忙的,不能说Presenter你来汇报工作我就得在,有事儿找我的秘书(接口)吧,我已经调教好(implements)她了,我的事儿她该懂的都懂,不该懂的我也没告诉她,然后,你懂得。然后Presenter的汇报工作就面向秘书(接口)了。
当然,我们可以举一反三。Presenter心想,Boss配了秘书,我也想弄一个。于是,Presenter也调教了一个,只不过档次低了点。以后Model干完活别来找我了,爷可是有身份的人。
说了这么多,其中废话最多。咱们的行话可是:
Talk is cheap ,show me the code
是时候表演真正的技术了。
首先是View的实现
IMainActivity就是操控UI变化的接口,由MainActivity实现,最终由Presenter来控制。
public interface IMainActivity {
public void showProgress();
public void hideProgress();
public void showBeatResult(String result);
public void showBuyResult(String result);
public void showZBResult(String result);
}
MainActivity的实现
public class MainActivity extends AppCompatActivity implements IMainActivity{
private PresenterMain mPresenter;
private ProgressBar progressBar;
private ImageView imageView;
private TextView textView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//作为Boss,想要一个管事的,还不是new一个就行了
//然后将Boss自己实现的接口传给Presenter,
//Presenter对结果的处理直接通过这个接口来实现
mPresenter = new PresenterMain(this);
progressBar = (ProgressBar) findViewById(R.id.progressBar);
imageView = (ImageView) findViewById(R.id.imageView);
textView = (TextView) findViewById(R.id.textView);
}
//Boss的日常
public void onClick(View view){
switch (view.getId()){
case R.id.btn_beat:
mPresenter.beatSomeBody("牧狗");
break;
case R.id.btn_buy_golden_chain:
mPresenter.buyGoldenChain();
break;
case R.id.btn_zhuang_bi:
mPresenter.zhuangBi();
break;
}
}
@Override
public void showProgress() {
progressBar.setVisibility(View.VISIBLE);
}
@Override
public void hideProgress() {
progressBar.setVisibility(View.INVISIBLE);
}
@Override
public void showBeatResult(String result) {
textView.setText(result);
imageView.setImageResource(R.mipmap.beat_somebody);
}
@Override
public void showBuyResult(String result) {
textView.setText(result);
imageView.setImageResource(R.mipmap.golden_chain);
}
@Override
public void showZBResult(String result) {
textView.setText(result);
imageView.setImageResource(R.mipmap.u_can_u_up);
}
作为一个Activity,内部只有操控UI的方法。
然后是Presenter
IPresenter就是作为一名Presenter的自我修养了,由Presenter实现。
里面提供了作为Presenter因该有的一些方法
注意onDestroy()
这个方法,用于当View销毁时,这个Presenter就没用了,毕竟老大死了,作为小弟的你怎么能苟活于世。(其实是如果Presenter不死的话,View就不会死,View不死的话,这块内存就测漏MemoryLeak
啦;想想,当你以为你杀死了View,而结果是他一直活着。总有一天他会找你报仇的)
public interface IPresenter {
public void beatSomeBody(String name);
public void buyGoldenChain();
public void zhuangBi();
public void onDestroy();
}
另外提供了一个接口OnResultListner ,这个用于监听Model的返回信息。毕竟,Model到底把事儿办得怎么样,我得知道,然后才好向Boss汇报。
public interface OnResultListner {
public void onBeatResult(String result);
public void onBuyResult(String result);
public void onZBResult(String result);
}
然后Presenter实现了上面俩接口
public class PresenterMain implements IPresenter, OnResultListner {
private IMainActivity iMainActivity;
private Model mModel;
public PresenterMain(IMainActivity iMainActivity) {
//Boss当然只能有一个
this.iMainActivity = iMainActivity;
//小弟想要几个就new几个
mModel = new Model(this);
}
/*
* Boss要打人啦
* */
@Override
public void beatSomeBody(String name) {
//正派小弟去打人,请boss耐心等待
if (null != iMainActivity) {
iMainActivity.showProgress();
mModel.beatSombody(name);
}
}
/*
* Boss要买金链子
* */
@Override
public void buyGoldenChain() {
//正派小弟去买金链子
if (null != iMainActivity) {
iMainActivity.showProgress();
mModel.buyGoldenChain();
}
}
/*
* Boss要装逼
* */
@Override
public void zhuangBi() {
//这个逼由小弟代您装了
if (null != iMainActivity) {
iMainActivity.showProgress();
mModel.zhuangbi();
}
}
@Override
public void onBeatResult(String result) {
iMainActivity.hideProgress();
iMainActivity.showBeatResult(result);
}
@Override
public void onBuyResult(String result) {
iMainActivity.hideProgress();
iMainActivity.showBuyResult(result);
}
@Override
public void onZBResult(String result) {
iMainActivity.hideProgress();
iMainActivity.showZBResult(result);
}
/*
* 当View挂了
* presenter绝不独活
* 解除与View的持有关系,然后坐等被GC回收
* */
@Override
public void onDestroy() {
iMainActivity = null;
}
}
最后是搞事儿的Model
同样,这是作为一个Model的基本素质,然后按这个素质招收小弟。
public interface IModelMain {
public void beatSombody(String name);
public void zhuangbi();
public void buyGoldenChain();
}
最后,找到了具有该素质的小弟
public class Model implements IModelMain{
private OnResultListner onResultListner;
private static Handler mHandler = new Handler();
public Model(OnResultListner onResultListner) {
this.onResultListner = onResultListner;
}
@Override
public void beatSombody(final String name) {
mHandler.postDelayed(new Runnable() {
@Override
public void run() {
onResultListner.onBeatResult(
name + "已经被教训了一顿"
);
}
},2000);
}
@Override
public void zhuangbi() {
mHandler.postDelayed(new Runnable() {
@Override
public void run() {
onResultListner.onZBResult(
"装逼成功"
);
}
},2000);
}
@Override
public void buyGoldenChain() {
mHandler.postDelayed(new Runnable() {
@Override
public void run() {
onResultListner.onBuyResult(
"老大,您的金链子"
);
}
},2000);
}
}
我们用一个Handler来模拟了任务并做了延迟2s,实际情况可能是作为后台任务执行一些延时的任务。
代码贴完,闪人。
源码地址 https://github.com/ysh666665/demo
参考博客 http://www.jianshu.com/p/9d40b298eca9