转载请注明出处:http://blog.csdn.net/yianemail/article/details/49365223
什么是MVP?
- View层主要是用于展示数据并对用户行为做出反馈。在Android平台上,他可以对应为Activity, Fragment,View或者对话框。
- Model是数据访问层,往往是数据库接口或者服务器的API。
- Presenter层可以想View层提供来自数据访问层的数据,除此以外,他也会处理一些后台事务。
也就是说在mvp模式中,view只单纯的展示ui,所有的业务逻辑处理放在Presenter中(通过接口与Molde,View)交互。
MVP的优点,为什么采用mvp的架构?
现在开发安卓人员都会遇到这种问题,那就是在一个逻辑非常的复杂的Activity中,代码量尝尝会达到数百甚至上千行,造成了activity既像view,但是某一定意义更像mvc的Controller。最终,你会发现“所有的事物都被连接到了一起”
,
这样的结果就是造就“万能的对象”。
With MVP
而MVP与MVC最不同的一点是M与V是不直接关联的也是就Model与View不存在直接关系,这两者之间间隔着的是Presenter层,其负责调控View与Model之间的间接交互,MVP的结构图如下所示,对于这个图理解即可而不必限于其中的条条框框,毕竟在不同的场景下多少会有些出入的。在Android中很重要的一点就是对UI的操作基本上需要异步进行也就是在MainThread中才能操作UI,所以对View与Model的切断分离是合理的。此外Presenter与View、Model的交互使用接口定义交互操作可以进一步达到松耦合也可以通过接口更加方便地进行单元测试。
MVP DEMO
我这里简单演示一个demo。主界面点击按钮,显示model层传递过来的数据,工程逻辑很简单,但是摸雀虽小,五脏俱全。
先看下目录结构(为了方便,项目结构没有分包,分包会优雅很多)
CallBack 是个回调接口,用来标示请求数据Success or Fail;
IModel :Model 层的接口
IPresenter : Presenter的接口
IView : ui层的接口(就是你界面有啥功能,然后你的activity实现此接口)
Weather Weathering: 两个java bean 没什么说的
然后我们说下具体的逻辑。既然Presenter是作为中间组件,那么就有两个作用:
1:负责view界面传递的功能请求,去Model 层得到数据
2:Persenter得到Model层的数据(一般是通过回调),然后负责把数据传递给View(View层得到的数据是相对被动的,是由Presenter传过来的)
看下界面需求:点击button ,TextView显示model传递的数据。
首先编写针对该界面的IView接口:
package com.example.luhuanju.myapplication;
/**
* Created by luhuanju on 15/10/23.
*/
public interface IView {
void showProgress();
void hideProgress();
void showError();
void setWetherInfo(Weather weather);
}
既然Model是负责请求数据逻辑的,IModel 接口就好写很多:(可以看到,参数有个回调接口,是Model请求数据Success 后回调给Persenter ,(Persenter需要实现此回调接口),)
/**
* Created by luhuanju on 15/10/23.
*/
public interface IModel {
void getInfo(String id,CallBack callBack);
}
于是,Persenter是这个样子的:
/**
* Created by luhuanju on 15/10/23.
*/
public class PresenterImpl implements IPresenter,CallBack {
IView mIView;
IModel mIModel;
public PresenterImpl(IView view){
mIView=view;
mIModel=new ModelImpl();
}
@Override
public void getInfo(String id) {
mIModel.getInfo(id,this);
}
@Override
public void onSuccess(Weather info) {
mIView.setWetherInfo(info);
}
@Override
public void Error() {
}
}
Model负责请求相关网络数据,我这边直接用假数据代替了~,你可以结合Retrofit更好的实现网络请求,看下Model:
/**
* Created by luhuanju on 15/10/23.
*/
public class ModelImpl implements IModel{
@Override
public void getInfo(String cityNO, final CallBack callBack) {
//直接模拟了一些假数据~!
//正常逻辑下,该处一般是负责请求网络得到数据的
WeatherInfo info=new WeatherInfo();
info.setCity("bei jing");
info.setCityid("101");
Weather weather=new Weather();
weather.setWeatherinfo(info);
//此处回调,作用就是把该数据负责回调给Presenter~!
callBack.onSuccess(weather);
}
}
//需要实现IView接口
public class MainActivity extends Activity implements IView,View.OnClickListener {
EditText editText;
Button button;
TextView textView2;
TextView textView;
TextView textView3;
IPresenter presenter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
init();
}
void init(){
editText=( EditText)findViewById(R.id.editText);
button=(Button)findViewById(R.id.button1);
textView=(TextView)findViewById(R.id.textView);
textView2=(TextView)findViewById(R.id.textView2);
textView3=(TextView)findViewById(R.id.textView3);
button.setOnClickListener(this);
//实例化Presenter
presenter=new PresenterImpl(this);
};
@Override
public void showProgress() {
}
@Override
public void hideProgress() {
}
@Override
public void showError() {
}
//接收到Presenter传过来的数据
@Override
public void setWetherInfo(Weather weather) {
WeatherInfo info=weather.getWeatherinfo();
textView.setText(info.getCity());
textView2.setText(info.getCity());
textView3.setText(info.getCityid());
}
@Override
public void onClick(View view) {
int id=view.getId();
switch (id) {
case R.id.button1:
presenter.getInfo(editText.getText().toString().trim());
break;
}
}
}
End
采用哪种软件设计模式都是为了达到如下目的,找到合适的加以运用就是最好的
资源下载:http://download.csdn.net/detail/yianemail/9214657
ps:这个是studio demo 。如果要eclipse 版本的私密我。