ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

MVP

2020-06-30 17:08:51  阅读:270  来源: 互联网

标签:MVP String void Presenter Model public View


 

一、简介

MVP 全称:Model-View-Presenter ;MVP 是从经典的模式MVC演变而来,它们的基本思想有相通的地方:Controller/Presenter负责逻辑的处理,Model提供数据,View负责显示。作为一种新的模式,MVP与MVC有着一个重大的区别:在MVP中View并不直接使用Model,它们之间的通信是通过Presenter (MVC中的Controller)来进行的,所有的交互都发生在Presenter内部,而在MVC中View会直接从Model中读取数据而不是通过 Controller。 

 

  • Model: 数据层,负责与网络层和数据库层的逻辑交互。
  • View: UI层,显示数据, 并向Presenter报告用户行为。
  • Presenter: 从Model拿数据,应用到UI层,管理UI的状态,响应用户的行为


 

1.1、使用MVP模式优势、

  • 模型与视图完全分离,我们可以修改视图而不影响模型
  • 可以更高效地使用模型,因为所有的交互都发生在一个地方——Presenter内部
  • 我们可以将一个Presenter用于多个视图,而不需要改变Presenter的逻辑。这个特性非常的有用,因为视图的变化总是比模型的变化频繁。
  • 如果我们把逻辑放在Presenter中,那么我们就可以脱离用户接口来测试这些逻辑(单元测试)

 

 

二、MVP模式与MVC模式对比
 
 2.1、MVC模式
 

  • Model(数据模型层):
  • 主要负责网络请求、数据库等其它 I/O 操作
  • View(视图层):
  • 主要包括 XML 布局文件(但功能较弱)
  • Controller(控制器层):
  • 一般就是 Activity 或者 Fragment,负责 MVC 整个流程的调度、协作。但是由于 XML 的视图处理能力较弱,需要 Activity 或者 Fragment 承担部分视图层工作。

MVC中是允许Model和View进行交互的,而MVP中很明显,Model与View之间的交互由Presenter完成。还有一点就是Presenter与View之间的交互是通过接口的。

还有一点注意:MVC中V对应的是布局文件,MVP中V对应的是Activity。

 2.2、MVP模式

  • Model(数据模型层):
  • 主要负责网络请求、数据库等其它 I/O 操作,和 MVC 中的 Model 层类似
  • View(视图层):
  • 主要是 Activity、Fragment、XML布局文件
  • Presenter(控制器层):
  • 自定义的 Presenter 类,类似于 MVC 中 Controller 的作用,是 MVP 中的核心,主要负责 Model 层和 View 层的交互

 

 

MVP模式通过Presenter实现数据和视图之间的交互,简化了Activity的职责。同时即避免了View和Model的直接联系,又通过Presenter实现两者之间的沟通。

总结:MVP模式减少了Activity的职责,简化了Activity中的代码,将复杂的逻辑代码提取到了Presenter中进行处理,模块职责划分明显,层次清晰。与之对应的好处就是,耦合度更低,更方便的进行测试。

 

 

 

下面说下,契约类

契约类的出现是在google mvp的例子中  https://github.com/android/architecture-samples/tree/todo-mvp
Contract 如其名,是一个契约,将Model、View、Presenter 进行约束管理,方便后期类的查找、维护。

与之前使用的MVP实现不同,官方的实现中加入了契约类来统一管理view与presenter的所有的接口,这种方式使得view与presenter中有哪些功能,一目了然,维护起来也方便,同时使得view与presenter一一对应,并有效地减少类的数目。

下面举例来说下 契约类的作用 

 

Activity页面

public class LoginActivity extends AppCompatActivity implements ILoginContract.ILoginView {

    @BindView(R.id.et_userName)
    EditText etUserName;
    @BindView(R.id.et_password)
    EditText etPassword;
    @BindView(R.id.btn_login)
    Button btnLogin;
    private ILoginContract.ILoginPresenter presenter;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        ButterKnife.bind(this);
        //创建P层
        presenter = new LoginPresenterImpl();
        presenter.attachView(this);
    }

    @Override
    public void showData() {

    }

    @OnClick(R.id.btn_login)
    public void onViewClicked() {
        //获取用户名、密码
        String userName = etUserName.getText().toString();
        String password = etPassword.getText().toString();
        //获取P层,触发请求动作
        presenter.requstLoginData(userName,password);
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        //解绑
        presenter.detachView(this);
    }
}

 

 

契约类,统一接口管理

 用于定义同一个界面的view和presenter的接口,通过规范的方法命名或注释,可以清晰的看到整个页面的逻辑。


public class LoginContact {
public interface ILoginContract {
    //V层接口
    public interface ILoginView {
        //数据显示
        public void showData();
    }

    //P层接口
    public interface ILoginPresenter<ILoginView> {
        //绑定
        public void attachView(ILoginView loginView);

        //解绑
        public void detachView(ILoginView loginView);

        //数据请求,请求M层数据,做登录处理
        public void requstLoginData(String userName, String password);

    }

    //M层接口
    public interface ILoginModel {
        //做登录的接口的请求
        public void containLoginResponseData(String userName, String password, CallBack callback);

        //接口回调
        public interface CallBack {
            //回显数据方法
            public void responseData();
        }
    }

}
 

 P层

public class LoginPresenterImpl implements ILoginContract.ILoginPresenter<ILoginContract.ILoginView> {
    ILoginContract.ILoginView loginView;
    private SoftReference<ILoginContract.ILoginView> reference;
    private ILoginContract.ILoginModel model;

    @Override
    public void attachView(ILoginContract.ILoginView loginView) {
        this.loginView = loginView;
        //软引用包裹
        reference = new SoftReference<>(loginView);
        //TODO 耦合性处理
        //M层
        model = new LoginModelImpl();
    }

    @Override
    public void detachView(ILoginContract.ILoginView loginView) {
        reference.clear();
    }

    @Override
    public void requstLoginData(String userName, String password) {
        model.containLoginResponseData(userName,password,new ILoginContract.ILoginModel.CallBack() {
            @Override
            public void responseData() {

            }
        });
    }
}
 

M层

public class LoginModelImpl implements ILoginContract.ILoginModel {

    @Override
    public void containLoginResponseData(final String userName, final String password, CallBack callback) {
        Runnable runnable = new Runnable() {
            @Override
            public void run() {
                requestLoginData(userName, password);
            }
        };
        new Thread(runnable).start();

    }

    private void requestLoginData(String userName, String password) {
        try {
            //携带用户名、密码的参数的URL
            //String request_url = Constant.LOGIN_URL + "?phone=" + userName + "&pwd=" + password;
            String request_url = Constant.BEAUTY_URL;
            //OKHttp做登录处理
            //创建OKHttpClient对象
            OkHttpClient client = new OkHttpClient.Builder().build();
            //表单请求体
            //FormBody formBody = new FormBody.Builder().build();
            //创建Requst请求对象
            //Request request = new Request.Builder().method("POST",formBody).url(request_url).build();
            Request request = new Request.Builder().url(request_url).build();
            //通过OKHttpClient对象调用newCall方法
            Response response = client.newCall(request).execute();
            //获取到Response,进行处理
            String responseData = response.body().string();
            //回显到P层
            Log.d("LoginModelImpl", responseData);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

Constant数据

public class Constant {
    //登录的URL
    public static final String LOGIN_URL = "*******";
 

}

总结:

mvp模式主要是将activity中的业务逻辑内容分离出去放到Model中处理,使得activity作为一个纯粹的View内容,只处理一些init的作用。同时通过Presenter作为Model和View的连接桥梁。当接口定义完后,编写代码思路就已经大致理清了,剩下的便是对大致的功能的具体实现,这个开发思路非常清晰。

其主要优势在于:activity的代码逻辑更加清晰,减少了大量冗余代码和回调,项目结构也清晰

劣势:需要大量的接口文件,presenter 文件也会有很多

 

 

标签:MVP,String,void,Presenter,Model,public,View
来源: https://blog.csdn.net/yangbin0513/article/details/106982493

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有