一个简单到不能再简单的 MVP 的例子

2,632 阅读5分钟
原文链接: www.jianshu.com
前言:

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 里面的操作

这里我们只是简单的一个点击事件,然后模拟网络获取数据,显示出来

  /** 布局文件 */

  

    



第二步:协议类的书写

协议类是约束我们的 P 层和 V 层要做的事,同时也是我们 P 层和 V层需要做的事。在这里我们需要同时对 P 层和 V 层做约束,因此需要两个接口。

由于 V 层我们只需要一个点击事件获取数据,因此我们可以这样写:

/** view */
public interface View {    
    void showData(List 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 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 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 list) {
        adapter.updateUi(list);
    }
}

当然这也是我们的 activity 要实现的功能,这里实现了 View 里面的方法,在上面的调用过程中会自动调用这个实现的方法,因此可以将数据带入 activity 中,这样就可以看到 P 层和 V 层是你中有我,我中有你。

好了,例子写完了,其中的 adapter 的代码就不再贴出来了,后面我会将代码的 github 地址贴上。当然这里只是最简单的一个小例子,同时也是自己对 MVP 模式的理解,并没有真正的网络访问,也没有复杂的逻辑处理,更没有进一步的进行封装,这只是一个小例子,如果有什么不妥的地方,还请大家多多指正,在这里先谢谢大家了。相较于我刚开始学习这种模式的时候,面对的都是一些复杂的集成的框架,什么 MVP+retrofit+Okhttp+……等等的组合一块的例子,其实我就是想了解一下什么是 MVP 而已,毕竟知识都是一步一步学来的,当然我们也不能止于当前,同时我也会在接下来逐渐的更新关于 MVP+……的一些例子,敬请期待(吐槽:不知道下一个帖子是何年何月了)。

写在最后:

这是我第一次写文章,感觉真的好难,当你下定决心的时候,剩下的就是时间了,当然我们也不可能拿全部的时间来写这个,毕竟我们还有自己的工作、任务要完成。一百半九十,当你真正要做时,才知道里面所要花的心血,真的非常感谢那些把知识写成帖子的那些人,让我这样的菜鸟也有机会获得一些学习资料,毕竟我们都是站在巨人肩膀上的人。

Tips:

github:
SimpleMVPApplication
推荐链接:
Android官方MVP架构示例项目解析
MVC模式