简单教你写MVP模式

简介: V层如果要更新数据,V层会通知P层,P层会去M层获取数据,然后P层再将拿到的数据传给V层,V层进而实现更新。

今天简单的来写一个MVP模式的demo,MVC跟MVP的区别网上一大堆,这里不多说;

平时我们的开发都是MVC模式的,下面我们写一个MVC的例子,然后在把它转为MVP模式,对比一下就很清楚之间的区别;

需求:页面上一个Button,点击Button发送网络请求,将请求成功后的信息用Toast弹出来;

MVC例子

public class MainActivity extends AppCompatActivity {
    private Button mBtnClick;
    private final String TAG = MainActivity.class.getSimpleName();
 
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        initView();
        onClickListener();
    }
 
    private void initView() {
        mBtnClick = findViewById(R.id.btn_click);
    }
 
    private void onClickListener() {
        mBtnClick.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                getData();
            }
        });
    }
 
    private void getData() {
        OkHttpClient client = new OkHttpClient();
        Request request = new Request.Builder()
                .url("https://wwww.baidu.com")
                .get()
                .build();
        Call call = client.newCall(request);
        call.enqueue(new Callback() {
            @Override
            public void onFailure(Call call, IOException e) {
                Log.i(TAG+" onFailure",e.toString());
            }
 
            @Override
            public void onResponse(Call call, final Response response) throws IOException {
                runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        Toast.makeText(MainActivity.this, response.toString(), Toast.LENGTH_LONG).show();
                    }
                });
            }
        });
    }
}

MVC会将所有的业务逻辑跟数据处理都写在一起,在功能多的情况下会显示很臃肿,沉重。

下面将上面的例子转换为MVP模式,使用MVP一定会用到interface,会写比较多的interface,这也是MVP模式的缺点。为了较少的创建接口类,可以定义了一个契约接口,把它们更加紧密的结合在一起,也方便查看,如下:

public interface IMainContract {
    //View层需要用到的interface
    interface IMainView{
        void toast(String Content);
    }
 
    //Model层需要用到的interface
    interface IMainModel{
        void click(Callback callback);
    }
 
    //Presenter层需要用到的interface
    interface IMainPresenter{
        void handlerData();
    }
}

View层

因为业务逻辑在M层,数据的处理在P层,所以V层只需要将数据显示出来就行,V层会通知P层数处理数据,P层处理后会回传给V层

public class MainActivity extends AppCompatActivity implements IMainContract.IMainView {
    private Button mBtnClick;
    private PresenterManager mPresenter;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        initView();
        mPresenter = new PresenterManager(this);
        onClickListener();
    }
 
    private void initView() {
        mBtnClick = findViewById(R.id.btn_click);
    }
 
    //按钮的点击事件
    private void onClickListener(){
        mBtnClick.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                mPresenter.handlerData();//让P层去处理数据
            }
        });
    }
 
    @Override
    public void toast(final String Content) {//用于显示数据
        runOnUiThread(new Runnable() {
            @Override
            public void run() {
                Toast.makeText(MainActivity.this, Content, Toast.LENGTH_LONG).show();
            }
        });
    }
}

Model层

网络请求数据在这一层,代码如下:

public class ModelData implements IMainContract.IMainModel {
 
    @Override
    public void click(Callback callback) {//使用了Callback,将获取到的数据回调给presenter处理
        OkHttpClient client = new OkHttpClient();
        Request request = new Request.Builder()
                .url("https://wwww.baidu.com")
                .get()
                .build();
        Call call = client.newCall(request);
        call.enqueue(callback);
    }
}

Presenter层

P层将从M层获取到的数据进行处理后,传给V层,V层将数据显示出来

public class PresenterManager implements IMainContract.IMainPresenter {
    private IMainContract.IMainModel model;
    private IMainContract.IMainView view;
 
    public PresenterManager(IMainContract.IMainView view) {//初始化view跟model
        this.view = view;
        model = new ModelData();
    }
 
    @Override
    public void handlerData() {
        model.click(new Callback() {
            @Override
            public void onFailure(Call call, IOException e) {
 
            }
 
            @Override
            public void onResponse(Call call, Response response) throws IOException {
                if (view != null)
                    view.toast(response.body().string());//让V层去更新UI
            }
        });
    }
}

好了,这就写完了,细心的人会发现,V层跟M层之间没有直接的联系,都是通过P层来完成的,没错,因为这就是MVP模式的核心,将V-M在结构上实现分离,P层是V-M之间沟通的桥梁,所以P层中会包含V层对象跟M层对象。

总结:V层如果要更新数据,V层会通知P层,P层会去M层获取数据,然后P层再将拿到的数据传给V层,V层进而实现更新。

看了上面的例子,可能有人会提出疑问,MVC明明比MVP简单,代码少,看起来也清晰。其实是这样,因为上面的例子太过于简单,MVP一般在多功能,需求大的项目中最能提现其优势,容易维护,项目结构上也会越来越清晰。

至于用MVC还是MVP,因人而异吧。

相关文章
|
6月前
|
Android开发
mvp架构
mvp架构
119 9
|
JavaScript 前端开发 C++
MVVM模式 VS MVP模式
MVP模式 使用jquery操作DOM,就是经典的MVP模式: M:数据模型 V:视图层 P:控制层 主要的关注点在P控制层,比如jquery通过响应视图层上用户的点击去请求ajax数据,再渲染更新视图层
86 0
MVVM模式 VS MVP模式
mvp架构优化
MVP优化的结构 mvp结构图.png view的结构 BaseView public interface BaseView { void showLoading(); void hideLoading(); } ...
1122 0
|
前端开发 Java 测试技术
|
前端开发 测试技术 Android开发
|
前端开发 Android开发 数据库