您的位置:首页 > 其它

Model-View-Presenter 设计模式

2015-01-28 15:29 453 查看
  你可能听过MVC设计模式,甚至你在各种框架(例:.Net)下都使用了该模式。然而当我尝试用一种新的设计模式去实现我的Android程序的时候,我发现了MVP模式。MVP和MVC最本质的区别是,MVP在present实现UI上的业务逻辑然后通过接口和外部通讯。

  下面我将通过例子来展现如何在Android程序里通过MVP模式来提高代码的可测试性(这里主要是单元测试)。我们的例子是这样的,在App要启动的时候,我们需要有个欢迎界面,这个欢迎界面后台运行着初始化数据的方法,在进入app主界面前,我们需要在欢迎界面提供一个进度条以此来检测是否网络环境正常,如果网络环境不ok,那我们显示一个错误页面。如果网络环境ok那就直接进入app主界面。

  建启动页的同时,我们同时创建一个presenter来负责model和view的通信。在本例中presenter应该具备两个功能:判断是否网络正常和view的处理,以下是我的工程的结构:



presenter模块会引用model模块,这里的model模块是ConnectStatus,他实现了IConnectStatus接口。

package com.sample.mvp.model;

/**
* Created by wuruize on 2015/1/27.
*/
public interface IConnectStatus {

public abstract boolean isOnline();
}


和你想象的一样,管理view模块的是实现了ISpalshView接口的Activity。实现了这个接口类将会被presenter控制,如下:

package com.sample.mvp.view;

/**
* Created by wuruize on 2015/1/27.
*/
public interface ISpalshView {

public abstract void hideProgress();

public abstract void showProgress();

public abstract void showNoInetErroMsg();

public abstract void moveToMain();
}


在编写Android程序的时候,view模块会首先被创建,然后会被交给presenter:

package com.sample.mvp.view.impl;

import android.support.v7.app.ActionBarActivity;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;

import com.sample.mvp.R;
import com.sample.mvp.presenter.SpalshPresenter;
import com.sample.mvp.view.ISpalshView;

public class SpalshActivity extends ActionBarActivity implements ISpalshView {

private SpalshPresenter mPresenter;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mPresenter = new SpalshPresenter(this);
}

@Override
protected void onResume() {
super.onResume();
mPresenter.didFinishLoading();
}

@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_main, menu);
return true;
}

@Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();

//noinspection SimplifiableIfStatement
if (id == R.id.action_settings) {
return true;
}

return super.onOptionsItemSelected(item);
}

@Override
public void hideProgress() {

}

@Override
public void showProgress() {

}

@Override
public void showNoInetErroMsg() {

}

@Override
public void moveToMain() {

}
}


首先我们初始化Activity,然后我们把Activity实例给presenter构造presenter实例,重写 onResume() 让presenter模块接管view模块,present代码如下:

package com.sample.mvp.presenter;

import com.sample.mvp.model.impl.ConnectStatus;
import com.sample.mvp.view.ISpalshView;

/**
* Created by wuruize on 2015/1/27.
*/
public class SpalshPresenter {

private ISpalshView mSpalshView;
private ConnectStatus mStatus;

public SpalshPresenter(ISpalshView view) {
this.mSpalshView = view;
mStatus = new ConnectStatus();
}

public void didFinishLoading() {
if(mStatus.isOnline()) {

} else {
mSpalshView.hideProgress();
mSpalshView.showNoInetErroMsg();
}
}
}


presenter模块会持有实现了ISpalshView接口的引用,实现IConnectStatus的model用于判断网络是否ok。基于此,我们可以通过view模块做不同的事情,和我们看到的一样,我们不需要知道view的具体实现(是被Activity实现还是其他)。如此,降低解耦。能够轻易作修改,进行单元测试。


  在单元测试的时候,你是不是有那样一个痛点,由于Activity功能元素功能都较为复杂,想要测试某个具体功能块的话,很浪费时间,降低了开发效率。而如果你使用了MVP模式,不需要依赖于View的具体实现,做到真正的test-driven development.

  声明:文章里面的东西基本来自于《50 Android Hacks》理解和翻译,特此感谢此书。

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: