美文网首页MVP系列
一个简单到不能再简单的 MVP 的例子

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

作者: zgfei | 来源:发表于2016-12-13 11:46 被阅读1021次
    前言:

    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模式

    相关文章

      网友评论

      • zgfei:谢谢,因为第一次写文章,所以表达的不是很好。
        HannyYeung:坚持下去就会很好
      • c32897ed7c37:浅俗易懂 支持一下

      本文标题:一个简单到不能再简单的 MVP 的例子

      本文链接:https://www.haomeiwen.com/subject/vfwvmttx.html