欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Android中的MVP模式入门解析

程序员文章站 2022-05-12 14:58:14
...

初衷

说实话,每次面试的时候,都会被问及Android的开发模式,我们用的无非就是MVC、MVP、MVVM等,有的开发者,干脆直接使用普通架构,就是,我干脆什么模式都不用,写一步看一步,最后导致自己的项目动一步则动全身,项目维护起来比较困难,导致后期新加入的同事不愿意去维护自己的项目,所以我们可以通过这些开发模式,来提高我们项目的可维护性

网上也有很多的大神,为我们讲解了MVP的搭建过程,但是我还是想再跟大家捋一捋,也算是加深一下印象,哈哈。。。好了,说了这么多,我们先来看一张图吧:

Android中的MVP模式入门解析

看了这张图,大家应该有所领悟,就算不懂,应该也在心里有点想法了,其实我们很多人有时候会误以为MVC和MVP其实差不多,但是,用了之后,再加上理解,你会发现,其实他们还是有本质区别的,MVP在一定程度上解耦了Activity中的试图和逻辑的关系,将他们分开,把所有的逻辑交由Presenter去处理,然后再通知Model去更新数据,然后显示在View中。

这样做的好处是什么?说句白话,就是方便后期维护,我们在更改数据的时候,就不用再去管Activity中的代码了,直接去Presenter中更改逻辑就好了,是不是很方便,话虽然不多,可能会有点绕,有时候每个人的理解也不一样,所以有可能会造成误区,我们用代码来说说,大家就会有一定的理解了

概述

我们用一些代码来讲讲,MVP模式的好处在哪里?

先让我们来看一下效果图吧,很简单:

Android中的MVP模式入门解析

其实很简单,就是保存两个参数,然后在显示出来,好吧,既然看到效果了,那大家是不是也很迫不及待的试一试呢?没关系,接下来我就告诉大家,如何搭建MVP架构模式,来完成Android项目基础架构搭建:

首先我们来看一下,项目的结构:

Android中的MVP模式入门解析

看起来就是这么回事,我创建了三个包名,分别是:Model,View,Presenter分别对应M,V,P,MVP的主要目的就是解耦业务逻辑和视图逻辑,接下来,我们看思路:

Model

也就是我们说的实体类,这个不多说肯定要有的,代码没啥,看一下就好了:
  1. UserBean.java
/**
 * Created by donny on 2017/10/9.
 */

public class UserBean {

    private int id;
    private String name;

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

}
  1. User.java
/**
 * Created by donny on 2017/10/9.
 */

public class User implements IUser {
    private UserBean bean;
    @Override
    public void SaveUserInfo(UserBean user) {
        this.bean = user;
    }

    @Override
    public UserBean LoadUserInfo() {
        if (bean != null){
            return bean;
        }
        return null;
    }
}
  1. IUser.java
/**
 * Created by donny on 2017/10/9.
 */

public interface IUser {

    void SaveUserInfo(UserBean user);

    UserBean LoadUserInfo();
}
这里大家要注意一下,IUser里面主要是接口,首先,我们要想好,在Presenter中要实现哪些逻辑,要用到哪些方法,然后就在这里定义哪些方法。User主要是IUser的实现,返回一些数据,具体返回那些数据,就有大家自己去根据实际情况而定了。

View

  1. IUserView.java
/**
 * Created by donny on 2017/10/9.
 */

public interface IUserView {

    UserBean getUser();

    void setUser(UserBean bean);
}

大家可以看一下,IUserView这个类里面的方法,很明显,一个是拿到数据,一个是把数据给别人,我们需要让我们的Activity去实现这个接口里面的方法,然后去做一些数据的显示或者获取。

上面我们说过,Presenter与View交互是通过接口。所以我们这里需要定义一个IUserView,难点就在于应该有哪些方法,我们看一眼效果图会发现一个是保存,一个是载入,所以我们就创建两个方法,分别是:getUser和setUser;

  1. MainActivity.java
package com.heytz.mvpdemo;

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;

import com.heytz.mvpdemo.modle.UserBean;
import com.heytz.mvpdemo.presenter.UserPresenter;
import com.heytz.mvpdemo.view.IUserView;

public class MainActivity extends AppCompatActivity implements IUserView {

    EditText edt_id, edt_name;
    Button btn_load, btn_save;
    TextView tv_show;

    UserPresenter presenter;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        presenter = new UserPresenter(this);
        initView();
        initEvent();
    }

    private void initEvent() {
        btn_load.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                presenter.loadUser();
            }
        });
        btn_save.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                presenter.saveUser();
                Toast.makeText(MainActivity.this, "保存完成", Toast.LENGTH_SHORT).show();
            }
        });
    }

    private void initView() {
        edt_id = (EditText) findViewById(R.id.edt_id);
        edt_name = (EditText) findViewById(R.id.edt_name);
        btn_load = (Button) findViewById(R.id.btn_load);
        btn_save = (Button) findViewById(R.id.btn_save);
        tv_show = (TextView) findViewById(R.id.tv_show);
    }

    @Override
    public UserBean getUser() {
        int id = Integer.valueOf(edt_id.getText().toString().trim());
        String name = edt_name.getText().toString().trim();
        if (name != null) {
            UserBean bean = new UserBean();
            bean.setId(id);
            bean.setName(name);
            return bean;
        }
        return null;
    }

    @Override
    public void setUser(UserBean bean) {
        if (bean != null) {
            tv_show.setText(bean.getId() + "\n" + bean.getName());
        }
    }
}

Presenter

这个才是我们今天的主角,先给大家看一下他的代码,虽然不多,但是它是连接Activity和Model的重要桥梁,所有的业务逻辑都在它里面完成:
  1. UserPresenter.java
package com.heytz.mvpdemo.presenter;

import com.heytz.mvpdemo.modle.IUser;
import com.heytz.mvpdemo.modle.User;
import com.heytz.mvpdemo.view.IUserView;

/**
 * Created by donny on 2017/10/9.
 */

public class UserPresenter {

    private IUserView userView;
    private IUser user;

    public UserPresenter(IUserView view) {
        this.userView = view;
        user = new User();
    }

    public void saveUser() {
        user.SaveUserInfo(userView.getUser());
    }

    public void loadUser() {
        userView.setUser(user.LoadUserInfo());;
    }
}

Presenter是用作Model和View之间交互的桥梁,那么应该有什么方法呢?

大家看到了,IUserview中主要有两个实现方法,主要用来实现从Activity中拿到数据,然后交给User这个类去进行操作,User类实现了IUser的接口,所以我们要在User类中实现一些对UserBean的操作,只要知道怎么去定义方法,如何操作,那么MVP模式其实不难
注意上述代码,其实我们的presenter要完成二者的交互,那么肯定需要二者的实现类。大致就是从View中获取需要的参数,交给Model去执行业务方法,执行的过程中需要的反馈,以及结果,再让View进行做对应的显示。

ok,我通过一个例子给大家分析了一下mvp架构搭建的过程,以上也是我对MVP的一个理解,如果大家有什么问题,欢迎留言和讨论,虽然有很多大神写了这方面的文章,但是每个人的理解可能会有偏差,所以我还是把自己的想法又写了一遍,欢迎大家讨论和吐槽。

最后附上demo下载地址