MVP架构
一、什么是MVP和MVP结构?
- MVP是由MVC演变而来的,然而MVP是Model, View和Presenter的简称。Model提供数据(Model并不 是必须
有的,但是一定会有View和Presenter),View负责显示,Presenter负责逻辑的处理。在MVP中View并不
直接使用Model,它们之间的通信是通过Presenter ,所有的交互都发生在Presenter内部。
在MVP模式里通常包含4个要素:
1、View: 负责绘制UI元素、与用户进行交互(在Android中体现为Activity);
2、View interface: 需要View实现的接口,View通过View interface与Presenter进行交互,降低耦合,方便进行单元测试;
3、Model: 数据处理和业务逻辑部分(有时也实现一个Model interface用来降低耦合);
4、Presenter: 作为View与Model交互的中间纽带,处理与用户交互的负责逻辑。
二、为什么要用MVP。
- 因为在Android中,Activity严重耦合了界面和数据获取层。这样不仅导致了Activity的类越来越庞大,
而且,如果修改数据获取层,可能也导致整个View 都要重写。也非常不利于模块和自动化测试。MVP使
View独立于数据,把大量的 逻辑从Activity中提取出来。把应用分层,每层都可以独立测试和变动。
三、MVP的实例代码。
- IView接口类
InterfaceSummaryView.java
/**
* View接口读取数据
* Created by Administrator on 2016/3/24.
*/
public interface InterfaceSummaryView {
void showData(VehicleModel vehicleModel); //显示数据
void concealProgressBar();//关闭进度条
void showSeparator();//显示分割线
void setData(VehicleModel vehicleModel);//给对象赋值
void ErrorPrompt(String message); //没有数据时候的提示语
String getSearchValue(); //获得关键字
String getVehicleId(); //获得车型ID
Boolean getFlag();//是否从搜索界面进来的
void NextToActivity(); //跳转到下一个界面
}
- 展示界面
VehicleSummaryActivity.java
/**
* 展示界面
* Created by Administrator on 2016/1/5.
*/
public class VehicleSummaryActivity extends BaseActivity implements View.OnClickListener,
InterfaceSummaryView {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.vehicle_summary);
initVehicleView();
presenter.loadData();
}
//初始化控件
private void initVehicleView() {
presenter = new PresenterVehicleSummary(this, this);
......
}
@Override
public String getSearchValue() {return getIntent().getExtras().getString(SEARCH_KEY); }
@Override
public String getVehicleId() {return getIntent().getExtras().getString(VEHICLE_ID);}
@Override
public Boolean getFlag() { return getIntent().getExtras().getBoolean(IS_SEARCH);}
/**
* 给控件赋值
*/
@Override
public void showData(VehicleModel vehiclemodel) {...... }
@Override
public void concealProgressBar() { progressBar.setVisibility(View.GONE);}
@Override
public void showSeparator() { separator.setVisibility(View.VISIBLE); }
@Override
public void setData(VehicleModel model) { vehicleModel = model; }
@Override
public void ErrorPrompt(String message) {
Toast.makeText(this, message, Toast.LENGTH_SHORT).show();
}
@Override
public void NextToActivity() {
new ActivityUtil().startMainActivity(this, vehicleModel.getModelName(), vehicleModel.getModelId());
}
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.back:
finish();
break;
case R.id.ll_part:
presenter.ToNextActivity();
break;
}
}
}
- Presenter类
PresenterVehicleSummary.java
/**
* Presenter类处理数据和刷新界面
* Created by Administrator on 2016/3/24.
*/
public class PresenterVehicleSummary {
private InterfaceSummaryView infoView;
private Activity mActivity;
private VehicleModel vehicleModel;
public PresenterVehicleSummary(Activity mActivity, InterfaceSummaryView infoView) {
this.mActivity = mActivity;
this.infoView = infoView;
}
/**
* 加载数据
*/
public void loadData() {
String url = "";
if (infoView.getFlag()) {
if (!StringUtils.isEmpty(infoView.getSearchValue()))
//根据关键字来查询的URL
url = ServiceEndPoint.GetSearchUri(SearchTypeEnum.SearchType.VIN.getType(), infoView.getSearchValue(), 0, 10);
} else {
if (!StringUtils.isEmpty(infoView.getVehicleId()))
//根据车型ID来查询的URL
url = ServiceEndPoint.GetVehicleModelsParticularsUri(infoView.getVehicleId());
}
JsonObjectRequest request = VolleyHelper.newJsonObjectRequest(url, null, new Response.Listener<JSONObject>() {
@Override
public void onResponse(JSONObject jsonObject) {
try {
infoView.concealProgressBar();
infoView.showSeparator();
if (infoView.getFlag()) {
if (jsonObject.toString().equals("{}"))
infoView.ErrorPrompt("没有查到该车的相关数据");
vehicleModel = GsonHelper.newGson().fromJson(jsonObject.get("result").toString(), VehicleModel.class);
} else {
vehicleModel = GsonHelper.newGson().fromJson(jsonObject.toString(), VehicleModel.class);
}
if (vehicleModel == null) {
infoView.ErrorPrompt("没有查到该车的相关数据");
} else {
infoView.showData(vehicleModel);
infoView.setData(vehicleModel);
}
} catch (JSONException e) {
e.printStackTrace();
}
}
}, new GenericErrorListener(mActivity) {
@Override
public void onErrorResponse(VolleyError error) {
super.onErrorResponse(error);
}
}, getAccessToken());
VolleySingleton.getInstance(mActivity).addToRequestQueue(request);
/**
* 跳转到下个页面
*/
public void ToNextActivity() {
if (vehicleModel == null) {
infoView.ErrorPrompt("暂无数据不能查看全车件");
} else {
infoView.NextToActivity();
}
}
public String getAccessToken() {
User user = User.getInstance(mActivity);
if (user == null)
return null;
return user.getAccessToken();
}
}
四、总结
MVP的优点
1、降低耦合度,模型与视图完全分离,可以修改视图而不影响模型。
2、可以更高效地使用模型,因为所有的交互都发生在一个地方——Presenter内部。
3、可以将一个Presenter用于多个视图,而不需要改变Presenter的逻辑。这个特性非常的有用,因为视图的变化总是比模型的变化频繁。
4、如果把逻辑放在Presenter中,那么就可以脱离用户接口来测试这些逻辑(单元测试)。
MVP的缺点
1、 Presenter中除了应用逻辑以外,还有大量的View->Model,Model->View的手动同步逻辑,造成Presenter比较笨重,维护起来会比较困难。
2、 由于对视图的渲染放在了Presenter中,所以视图和Presenter的交互会过于频繁。
3、 如果Presenter过多地渲染了视图,往往会使得它与特定的视图的联系过于紧密。一旦视图需要变更,那么Presenter也需要变更了。