简单教你写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,因人而异吧。

相关文章
|
2月前
|
Android开发
mvp架构
mvp架构
45 9
|
2月前
|
前端开发 测试技术 数据处理
安卓开发中的MVP架构模式深度解析
【4月更文挑战第30天】在移动应用开发领域,模型-视图-呈现器(Model-View-Presenter, MVP)是一种广泛采用的架构模式。它旨在通过解耦组件间的直接交互来提高代码的可维护性和可测试性。本文将深入探讨MVP在安卓开发中的应用,揭示其如何促进代码的模块化,提升用户界面的响应性,并简化单元测试过程。我们将从理论概念出发,逐步过渡到实践案例,为读者提供一套行之有效的MVP实施策略。
|
设计模式 网络协议 前端开发
MVP 架构最终审判 —— MVP 解决了哪些痛点,又引入了哪些坑?(一)
MVP 架构最终审判 —— MVP 解决了哪些痛点,又引入了哪些坑?(一)
70 0
|
安全 前端开发 网络协议
MVP 架构最终审判 —— MVP 解决了哪些痛点,又引入了哪些坑?(三)
MVP 架构最终审判 —— MVP 解决了哪些痛点,又引入了哪些坑?(三)
114 0
|
存储 缓存 前端开发
MVP 架构最终审判 —— MVP 解决了哪些痛点,又引入了哪些坑?(二)
MVP 架构最终审判 —— MVP 解决了哪些痛点,又引入了哪些坑?(二)
91 0
|
JavaScript 前端开发 C++
MVVM模式 VS MVP模式
MVP模式 使用jquery操作DOM,就是经典的MVP模式: M:数据模型 V:视图层 P:控制层 主要的关注点在P控制层,比如jquery通过响应视图层上用户的点击去请求ajax数据,再渲染更新视图层
69 0
MVVM模式 VS MVP模式
mvp架构优化
MVP优化的结构 mvp结构图.png view的结构 BaseView public interface BaseView { void showLoading(); void hideLoading(); } ...
1104 0
|
前端开发 Java 测试技术
|
前端开发 测试技术 Android开发