今天是国庆节,祝你们节日快乐,愿祖国愈加繁荣昌盛。假期程序员也不能偷懒,更新一些博文吧。前端
看到封面图片喜欢NBA的人可能很容易就想到了最有价值球员。可是此mvp非彼MVP,此mvp指的是如今Android开发中比较常见的一种软件架构模式。mvp架构模式是Google官方推荐的架构模式,特别是近年来的新项目,mvp+retrofit+rxjava+dragger2配合使用已经在引领程序界的潮流了,在github上能够轻易的搜到一大堆这样的开源项目。前端时间笔者也在公司的一个sdk上进行了尝试,在此算是作个简单的总结吧。本文主要介绍什么是mvp架构模式,还有这种架构模式的优点以及如何使用它搭建你的项目。java
1、mvp为什么物git
我以前在公司项目中作尝试的时候,提交代码后公司同事曾问过我这个问题,程序员
我当时做了个简单的解释,这也是我学习过程当中总结出来的,若是要作一个比较正规的定义,我以为应该这么说:mvp 是从经典的mvc模式演变过来的,其基本思路都是相通的。其中M是model模型,提供业务数据;P是Presenter控制者,进行逻辑处理。V是View视图,显示数据。在MVP中View并不直接使用Model,它们之间的通讯是经过Presenter 来进行的,全部的交互都发生在Presener内部。在笔者的世界里,mvp架构模式的定义就是这样的,若是你看到这里以为难以接受这个定义,或者你认为这是错误的观点,就不建议你继续往下看了,建议直接留言联系笔者进行探讨。github
2、mvp架构模式的优点编程
若是你读到这里,说明你应该是已经接受笔者对mvp架构模式的定义了。接下来要阐述的是mvp架构模式的优点。众所周知,Android原生应用开发使用的是Java语言(至少目前绝大多数是),Java语言是面向对象的,面向对象的六大原则其中之一是单一职责原则,它的官方定义是There should never be more than one reason for a class to change,应该有且仅有一个缘由引发类的变动。说到底就是解耦合。对,解耦合,这就是mvp架构模式的终极目标,也是它最大的优点。为何要把架构里的各个层次分得清清楚楚,每一个层面负责什么,不该该负责负责,如何组合起来都须要严格的定义起来,你要知道,每一种架构都不是编码规范,也不是组织代码的规范,它们都是一种思惟方式。因此在实践中你永远要记住你为何使用mvp架构模式,切忌忘记初衷,为了炫酷而在使用mvp。json
3、mvp架构模式的简单实践服务器
没错,在码农的世界里任何语言都是苍白无力的,仍是代码来的实际。稍安勿躁,代码立刻就来。可是仍是要提醒你们,只会写代码的不叫程序员,叫代码搬运工(就是搬砖的),学会编程以后就要升华一下,去掌握编程思想,以让你的代码更优雅,这句话是前几天老大跟我说的,在此送给你们。网络
为演示mvp架构模式的使用,笔者写了一个简单的小demo,demo主要功能是去服务器请求App版本更新的信息,服务器会返回版本信息,包括最新版本名,一个提示字段,还有是否须要更新的字段,将返回的数据封装Version实体类,代码以下:架构
public class Version {
//是否有新版本
private String hasNewVersion;
//描述
private String desc;
//最新版本名
private String latest_version;
public String getHasNewVersion() {
return hasNewVersion;
}
public String getDesc() {
return desc;
}
public String getLatest_version() {
return latest_version;
}
public void setHasNewVersion(String hasNewVersion) {
this.hasNewVersion = hasNewVersion;
}
public void setDesc(String desc) {
this.desc = desc;
}
public void setLatest_version(String latest_version) {
this.latest_version = latest_version;
}
}
主界面有两个TextView,一个用于显示版本名,一个用于显示版本的描述,还有一个按钮,点击按钮会触发请求,代码以下:
public class VersionActivity extends AppCompatActivity implements VersionView{
private TextView tv_versionName;
private TextView tv_desc;
private VersionPresenter mVersionPresenter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_mvp);
mVersionPresenter=VersionPresenter.getInstance(this,this);
tv_desc=(TextView) findViewById(R.id.tv_desc);
tv_versionName=(TextView) findViewById(R.id.tv_versionname);
findViewById(R.id.tv_but).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
mVersionPresenter.getNewVersion("http://10.180.152.101:8080/NetWorkServer/updateappversion"+"?currentversion=1.4");
}
});
}
@Override
public void showVersionNameAndDesc(Version version) {
tv_versionName.setText("最新版本名: "+version.getLatest_version());
tv_desc.setText(version.getDesc());
}
@Override
public void showToast(String msg) {
Toast.makeText(VersionActivity.this, msg, Toast.LENGTH_LONG).show();
}
}
该Activity实现了VersionView接口,这就是mvp中的view层,用于跟用户交互,显示数据。咱们能够看到VersionPresenter的初始化,VersionPresenter属于presenter层,用于处理view与model层的通讯,不让view直接操做model,可见用户点击按钮后,就通知VersionPresenter去获取版本信息,至于如何获取版本信息,presenter层会交给对应的model去进行处理,下面是VersionPresenter的代码:
public class VersionPresenter extends IPresenter {
private static VersionPresenter mVersionPresenter;
private VersionModel mVersionModel;
private VersionView mVersionView;
private Context mContext;
private VersionPresenter(Context context,IView view){
this.mContext=context;
this.mVersionView=(VersionView) view;
this.mVersionModel=new VersionModel();
}
public static VersionPresenter getInstance(Context context, VersionView view){
if (mVersionPresenter==null){
synchronized (VersionPresenter.class){
if (mVersionPresenter==null){
mVersionPresenter=new VersionPresenter(context,view);
}
}
}
return mVersionPresenter;
}
//获取最新版本
public void getNewVersion(String url){
mVersionModel.getNewVersion(mContext,url, new VersionModel.VersionCallback() {
@Override
public void onVersionCallback(final Version version) {
((Activity)mContext).runOnUiThread(new Runnable() {
@Override
public void run() {
mVersionView.showVersionNameAndDesc(version);
if (version.getHasNewVersion().equals("true")){
mVersionView.showToast("App有新版本,请更新");
}
}
});
}
});
}
}
用户通知presenter后,presenter就把view的需求通知model层,数据操做交给model层去作具体实现,能够见到在VersionPresenter的getNewVersion方法中只是把view传过来的参数给到model,具体的网络请求交给VersionModel去实现,下面是VersionModel的具体实现:
public class VersionModel implements IModel {
public interface VersionCallback {
void onVersionCallback(Version version);
}
private HttpURLConnection httpURLConnection = null;
private InputStream inputStream = null;
private BufferedReader bufferedReader = null;
public void getNewVersion(Context context,final String url, final VersionCallback versionCallback) {
new Thread(new Runnable() {
@Override
public void run() {
try {
httpURLConnection = (HttpURLConnection) new URL(url).openConnection();
httpURLConnection.connect();
inputStream = httpURLConnection.getInputStream();
bufferedReader = new BufferedReader(new InputStreamReader(inputStream, "utf-8"));
StringBuilder stringBuilder = new StringBuilder();
String tempLine = null;
while ((tempLine = bufferedReader.readLine()) != null) {
stringBuilder.append(tempLine).append("\n");
}
String data = stringBuilder.toString();
Log.e("data", data);
JSONObject jsonObject=null;
jsonObject = new JSONObject(data);
Version version=new Version();
version.setLatest_version(jsonObject.optString("latest_version"));
version.setDesc(jsonObject.optString("desc"));
version.setHasNewVersion(jsonObject.optString("hasNewVersion"));
versionCallback.onVersionCallback(version);
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
bufferedReader.close();
inputStream.close();
} catch (Exception e) {
}
}
}
}).start();
}
}
VersionModel去执行网络请求,获取到VersonView须要的数据而后回调到VersionPresenter,再由VersionPresenter通知VersonView去作UI的变化或者其余一些操做。纵观整个过程能够发现,view层和model层没有一丝耦合,这就是mvp架构模式的初衷,作到了松耦合,view,model,presenter每一层负责自身的工做,毫不越界。
总结
因为服务器代码也是本身写的,只有一个请求接口,数据的交互也很简单,可是麻雀虽小五脏俱全,服务器端跟客户端都在尽可能模拟实际开发中的流程,真个mvp架构模式的基本流程都有了,在此也附上源码地址,源码中有服务器和客户端的代码:https://github.com/shanyezhihe/mvpdemo.git
扫码关注本公众号