前言:
MVP 模式貌似已经火了很长一段时间了,直到今天才有时间来研究一下,并不是工作原因导致没有时间,而是有时间全用在蹉跎岁月上了,都是泪啊。
看到网上有很多关于 MVP 的帖子和例子,当然俺们也是学习他们那里来的,关键是要变成自己的东西啊。那么俺们就开始吧!
什么是 MVP???
老生常谈,先来说一说什么是 MVP 吧!因为网上有很多关于 MVP 的介绍,因此这里就不做过多的介绍。
先来看看 MVC 模式图
mvc.png
这里我们可以对比一下 MVP 的模式图
mvp.png
这里我们可以看都相较与 MVC 模式 MVP 模式的模块之间的关系更加明确。主要区别在于 Presenter 和 Control 之间。
这里有一个很好的关于两者之间区别的讲解:Android 你应该学会的设计模式MVP
当然图片都是从这篇文章中直接拿来的(自己笨没办法)。非常感谢这篇文章的作者。
当然这篇文章的主要目的是通过代码进行讲解 MVP 模式的工作流程,因此一些概念性的东西,就请自行百度吧!
例子:
首先我们先大致说明一下 MVP 的工作流程,那就是接口。
MVP 将 M 层,P 层和 V 层进行了解耦,每一个模块负责自己的任务,而 V 层再也不会去处理有关数据方面的东西,这个任务全权由 M 层接手了,P 层主要负责逻辑,V 层就负责显示就行了。而 P 层和 V 层之间的通信就是通过接口来完成的。
首先看一下我们的工程目录
工程目录.png
在 MVP 模式下,新增了的文件夹有contract,module,presenter
contract:协议包,是 V 层和 P 层交流的桥梁
module:M 层
presenter:P 层
第一步:确定我们的 activity 里面的操作
这里我们只是简单的一个点击事件,然后模拟网络获取数据,显示出来
/** 布局文件 */
<Button
android:id="@+id/bt_get_data"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="get data" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.v7.widget.RecyclerView
android:id="@+id/rv_show_data"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</LinearLayout>
第二步:协议类的书写
协议类是约束我们的 P 层和 V 层要做的事,同时也是我们 P 层和 V层需要做的事。在这里我们需要同时对 P 层和 V 层做约束,因此需要两个接口。
由于 V 层我们只需要一个点击事件获取数据,因此我们可以这样写:
/** view */
public interface View {
void showData(List<StringModel> list);
}
而相对于 P 层我们对应的应该是获取数据,在这里是这样写的:
/** presenter */
public interface Presenter {
void getData();
}
当然我们也可以用 Google 给的 demo 里面的写法,这里就不多说了,因为以后我们也会那么做。
第三步:确定 presenter 和 view 的实现类
我们已经确定了 P 层和 V 层的功能,当然我们要去实现这里的方法
对应的 MainPresenter 的写法是:
/** 实现接口 */
public class MainPresenter implements Presenter {
View view;
public MainPresenter(View view) {
this.view = view;
}
@Override
public void getData() {
List<StringModel> stringModels = NetWorkConnection.setList();
view.showData(stringModels);
}
}
这里我们可以看到,我们只是调用了 M 层的方法,获取数据,然后将数据传给 V 层,M 层和 V 层并没有直接的接触,而是通过 P 层来传递,这样就可以将 M 层和 V 层分离。M 层专注于自己的数据获取,V 层专注于自己的数据展示,P 层则负责之间的桥梁和逻辑处理。
在构造方法里我们需要将对应的 V 层的对象传递进来,以便调用数据的显示的方法。在调用 view.showData(stringModels); 的同时,会调用 View 的实现类。接下来我们就开始实现这个 View:
/** 实现接口 */
public class MainActivity extends AppCompatActivity implements com.zgf.simplemvpapplication.contract.View{
private Button btGetData;
private RecyclerView rvShowData;
private List<StringModel> list;
private MainAdapter adapter;
private Presenter presenter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initView();
initData();
initListener();
}
private void initView() {
btGetData = (Button) findViewById(R.id.bt_get_data);
rvShowData = (RecyclerView)
findViewById(R.id.rv_show_data);
}
private void initData() {
list = new ArrayList<>();
adapter = new MainAdapter(this, list);
rvShowData.setLayoutManager(new LinearLayoutManager(this));
rvShowData.setAdapter(adapter);
presenter = new MainPresenter(this);
}
private void initListener() {
btGetData.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
presenter.getData();
}
});
}
@Override
public void showData(List<StringModel> list) {
adapter.updateUi(list);
}
}
当然这也是我们的 activity 要实现的功能,这里实现了 View 里面的方法,在上面的调用过程中会自动调用这个实现的方法,因此可以将数据带入 activity 中,这样就可以看到 P 层和 V 层是你中有我,我中有你。
好了,例子写完了,其中的 adapter 的代码就不再贴出来了,后面我会将代码的 github 地址贴上。当然这里只是最简单的一个小例子,同时也是自己对 MVP 模式的理解,并没有真正的网络访问,也没有复杂的逻辑处理,更没有进一步的进行封装,这只是一个小例子,如果有什么不妥的地方,还请大家多多指正,在这里先谢谢大家了。相较于我刚开始学习这种模式的时候,面对的都是一些复杂的集成的框架,什么 MVP+retrofit+Okhttp+……等等的组合一块的例子,其实我就是想了解一下什么是 MVP 而已,毕竟知识都是一步一步学来的,当然我们也不能止于当前,同时我也会在接下来逐渐的更新关于 MVP+……的一些例子,敬请期待(吐槽:不知道下一个帖子是何年何月了)。
写在最后:
这是我第一次写文章,感觉真的好难,当你下定决心的时候,剩下的就是时间了,当然我们也不可能拿全部的时间来写这个,毕竟我们还有自己的工作、任务要完成。一百半九十,当你真正要做时,才知道里面所要花的心血,真的非常感谢那些把知识写成帖子的那些人,让我这样的菜鸟也有机会获得一些学习资料,毕竟我们都是站在巨人肩膀上的人。
Tips:
github:
SimpleMVPApplication
推荐链接:
Android官方MVP架构示例项目解析
MVC模式
网友评论