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

前言:

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

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 202,980评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,178评论 2 380
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 149,868评论 0 336
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,498评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,492评论 5 364
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,521评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,910评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,569评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,793评论 1 296
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,559评论 2 319
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,639评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,342评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,931评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,904评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,144评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,833评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,350评论 2 342

推荐阅读更多精彩内容