一,前言:
关于Android程序的构架, 当前最流行的模式即为MVP模式, Google官方便提供了Sample代码来展示这种模式的用法.Repo地址: android-architecture.
之所以人们会提到MVP这种设计模式,是因为它与传统的MVC模式相比,使得view层与model层完全解耦,作为view层的activity或者fragment不再臃肿,特别是交互逻辑比较复杂的情况下尤为明显。
二,MVC与MVP对比:
对于MVC与MVP的比较,网上有许多资料,我这里就不详细阐述了,下面就通过两种模式的对比图来简单的总结一下吧。
MVC模式图 MVP模式图总结:
MVC中的视图和数据是互相耦合在一起的,只要对其中一部分加以改动,其他和之相关的数据和视图都要受到牵连;而MVP中的数据和视图则是通过中间的presenter来连接的。View不直接与Model交互 ,而是通过与Presenter交互来与Model间接交互。通常Presenter与View的交互是通过接口来进行的,更有利于添加单元测试。
三,简单案例
一开始接触MVP设计模式时,也是有点分不清头脑,主要是其中相关的类变多了,各种接口和实现类,有点让人抓狂。后面通过参考了网上几遍相关的案例文章,自己总结了一下,按照一定的思路来写,还是清楚很多。下面我就把自己总结的方法一步步通过案例来实现下,有不足之处,还望大家指正。
文中例子是个简单的请求网络,获取天气的情景。废话不多说,先看实现步骤。
步骤一:先根据业务要求,思考界面主要有哪些实现及展示效果,从而设计view层的接口
/**
* 定义界面的一些行为状态
* Created by Administrator on 2018/4/2.
*/
public interface IgetWeatherView {
void showLoading();
void hideLoading();
void getWeatherFialed();//获取天气失败
void getWeatherSuccess(WeatherBean.WeatherInfo weatherInfo);//获取天气成功
void displayWeatherInfo(WeatherBean.WeatherInfo weatherInfo);//展示天气结果
}
步骤二:根据需要的获取的数据,定义数据层的基本接口
public interface IWeahter {
void getWeatherInfo(Context mContext,String url, WeatherListener weatherListener);
/**
* 获取天气结果接口回调
*/
interface WeatherListener{
void getSuccess(WeatherBean.WeatherInfo weatherBean);
void getFailed();
}
}
步骤三:设置数据获取的实现类(真实获取数据的地方)
public class WeatherImpl implements IWeahter{
@Override
public void getWeatherInfo(Context mContext, String url, final WeatherListener weatherListener) {
VolleyRequestUtil.requestGet(mContext, url, "weather", WeatherBean.class, new VolleyListenerInterface(mContext,
VolleyListenerInterface.mListener,VolleyListenerInterface.mErrorListener) {
@Override
public void onSuccess(Object result) {
WeatherBean weatherBean = (WeatherBean) result;
weatherListener.getSuccess(weatherBean.weatherinfo);
}
@Override
public void onError(VolleyError error) {
weatherListener.getFailed();
}
});
}
}
步骤四:设计提供逻辑交互的presenter层,该层必须持有view和model层的引用,然后在逻辑交互过程中把两者进行关联。
public class WeatherPresenter {
private IWeahter iweather;
private IgetWeatherView getWeatherView;
public WeatherPresenter (IgetWeatherView getWeatherView){
this.getWeatherView= getWeatherView;
iweather= new WeatherImpl();
}
/**
* 获取天气信息
* @param context
*/
public void getWeatherInfo(Context context){
getWeatherView.showLoading();
iweather.getWeatherInfo(context, "http://www.weather.com.cn/data/sk/101010100.html", new IgetWeatherView .WeatherListener() {
@Override
public void getSuccess(WeatherBean.WeatherInfo weatherInfo) {
getWeatherView.hideLoading();
getWeatherView.getWeatherSuccess(weatherInfo);
getWeatherView.displayWeatherInfo(weatherInfo);
}
@Override
public void getFailed() {
getWeatherView.hideLoading();
getWeatherView.getWeatherFialed();
}
});
}
步骤五,view层的实现(Activity)。有了presenter,activity的具体实现只要实现view层的基本接口即可,剩下的只是利用presenter做简单的界面实现
public class MainActivity extends FragmentActivity implements IgetWeatherView{
private Button request_btn;
private TextView display_weather_tv;
private WeatherPresenter weahterPresenter;
private ProgressBar progressbar;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initView();
initListener();
}
private void initView() {
display_weather_tv = (TextView) findViewById(R.id.display_weather_tv);
request_btn= (Button) findViewById(R.id.request_btn);
progressbar= (ProgressBar)findViewById(R.id.progressbar);
weahterPresenter= new WeatherPresenter(this);
}
private void initListener() {
request_btn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
weahterPresenter.getWeatherInfo(MainActivity.this);
}
});
}
@Override
public void showLoading() {
progressbar.setVisibility(View.VISIBLE);
}
@Override
public void hideLoading() {
progressbar.setVisibility(View.GONE);
}
@Override
public void getWeatherFialed() {
Toast.makeText(this,"获取天气信息失败",Toast.LENGTH_SHORT).show();
}
@Override
public void getWeatherSuccess(WeatherBean.WeatherInfo weatherInfo) {
Log.d("TAG", "city is " + weatherInfo.getCity());
Log.d("TAG", "temp is " + weatherInfo.getTemp());
Log.d("TAG", "time is " + weatherInfo.getTime());
}
@Override
public void displayWeatherInfo( WeatherBean.WeatherInfo weatherInfo) {
display_weather_tv.setText("city is "+weatherInfo.getCity() +
"temp is "+weatherInfo.getTemp() +
"time is "+weatherInfo.getTime());
}
最后的话:
上述例子中只贴了核心代码,其中网络是自己分装的volley请求,这部分内容以后有时间再总结一下。使用MVP模式后发现,代码量和类确实变多了,不过回过头来,看activity的代码,确实简洁了很多。可能这个例子还不是很明显,不过对于项目比较大,界面逻辑比较多的情况下,使用MVP的模式的确能放大其优势。不过,最终,在自己的项目中该使用什么模式,还是取决于具体项目大小以及复杂程度,还有团队的协作情况。总之,没有最好的模式,只有最适合团队的模式。不过,作为一名android开发者,每一种设计模式都应该了解,这样在将来要用到的时候才能随心所欲的使用,不至于犯怵。好了,关于MVP设计模式就写到这里,大家有什么疑问的,欢迎一起交流学习。
网友评论