美文网首页
Android MVP的简单实现

Android MVP的简单实现

作者: JokerHerry | 来源:发表于2017-11-28 20:21 被阅读0次

一个好的好的设计模式可以帮我们很好的管理我们的代码,也会方便于我们的后期的扩展。特别是针对我们这样的新手,学好一个好的代码管理是很有必要的。所以今天,和大家一起学习一下MVP模式。

一、MVP设计模式概述

什么是MVP设计模式

MVP,分别是Model-View-Presenter,即模型-视图-提出者。
Model:模型,实现业务逻辑和实例生成。
View:视图,对应的界面布局,以及界面布局的方法。
Presenter:一个活动中,主要的业务交互,作为view和model的中间传达者。

什么是MVC设计模式

MVP,分别是Model-View-Presenter,即模型-视图-控制器。
Model:模型,实现业务逻辑和实例生成。
View:视图,对应的界面布局,以及界面布局的方法。
Controllor:作为页面的控制器,响应view的交互,对应于Android中的Activity

对比

这么说可能不是很清晰,我们用两张图片来描述一下。


MVP与MVC对比

但是在Android我们的可以知道,其实Avtivity不仅要处理view的呈现,还要负责处理页面的业务逻辑,显得Activity不仅像view,又像controllor的结合体,导致Acitivity整体臃肿,超过1000行都是常事。

所以,为了更好的解耦这样的情况,让Activity更好的只关心页面的呈现,将主要的业务交互放置在presenter中实现,让Presenter作为view与model的中间传递者。减少Activity的体积。降低耦合度。

在MVP模式中,我们要做到,view层和model不能直接通信,要想通信,必须通过Persenter这一中间件。并且,view,model,presenter都是接口,之间的通讯也都是通过接口实现的。

二、 MVP的简单实现

接下来我们通过一个基础的实例,让我们来实现一个简单的MVP模式的登录界面。从实例的角度,我们来分析一个具体的MVP模式。看看他是怎样实现解耦,以及明显的内容划分。

Model层:

model层是用来实现某一层里面的业务逻辑。
那么,在一个登录界面中,我的model层就是实现登录密码检验的功能。
首先,我们需要有一个对象类,来表达我们需要检验的对象。

public class User {
    private String name;
    private String password;

    public User(String name,String password){
        this.name = name;
        this.password = password;
    }
    ...省略getter和setter
}

然后我们需要一个LoginModel的接口函数,来申明我们的登录所需要的函数。

public interface LoginModel {
    void login(User user);
}

其次是model的实现类,实现我们刚才在LoginModel中申明的login函数。
这里我们延时2秒钟,用于模拟登陆效果。

public class LoginModelImpl implements LoginModel{
    @Override
    public void login(User user) {
        final String name = user.getName();
        final String password = user.getPassword();

        new Handler().postDelayed(new Runnable() {
            @Override
            public void run() {
                Boolean error =false;
                if (TextUtils.isEmpty(name)){
                    error = true;
                    //输入错误
                    System.out.println("输入错误");
                }
                if (TextUtils.isEmpty(password)){
                    error = true;
                    //输入错误
                    System.out.println("输入错误");
                }
                if(!error){
                    //登录成功
                    System.out.println("登录成功");
                }
            }
        },2000);
    }
}

View层:

对应的界面布局,以及界面布局的方法。
这里我们需要实现的waitDialog的显示与消失,以及登录成功和失败的提醒,所以建立我们的view接口类,LoginView.

public interface LoginView {
    void loginSuccess();
    void ErrorPass();
    void ErrorEnter();

    void showDialog();
    void hideDialog();
}

然后我们的实例就是Activity,使Acitivity继承我们的接口,实现我们接口中的方法。

    //申明persenter实例
    LoginPresenter presenter;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_login);
        ButterKnife.bind(this);

        btn.setOnClickListener(this);
        //通过Presenter实例类申明presenter
        presenter = new LoginPresenterImpl(this);
    }
    

    @Override
    public void loginSuccess() {
        Toast.makeText(this,"登录成功",Toast.LENGTH_SHORT).show();
    }

    @Override
    public void ErrorPass() {
        Toast.makeText(this,"密码错误",Toast.LENGTH_SHORT).show();
    }

    @Override
    public void ErrorEnter() {
        Toast.makeText(this,"输入错误",Toast.LENGTH_SHORT).show();
    }

    @Override
    public void showDialog() {
        loginProgress.setVisibility(View.VISIBLE);
    }

    @Override
    public void hideDialog() {
        loginProgress.setVisibility(View.GONE);
    }
    
    @Override
    public void onClick(View v) {
        User user = new User(name.getText().toString(), password.getText().toString());
        //将检验事件回调给presenter,让他通知model进行检验
        presenter.checkLogin(user);
    }
}

Presenter层:

接下来是重点了,我们的Presenter类。
传递
作为view和model的中间传达者。view告诉presenter需要检验了,然后presenter在告诉model,并把得到的user值给model,让model进行检验。
申明presenter的接口类。

public interface LoginPresenter {
    void checkLogin(User user);
}

接口实现类LoginPresenterImpl,我们在presenter的实例中,获取到view和model的实例,然后在里面对其进行信息传递。

public class LoginPresenterImpl implements LoginPresenter,LoginModelListener{
    LoginView view;
    LoginModel model;

    public LoginPresenterImpl(LoginView loginView){
        //从Activity中获取到对view的引用
        this.view = loginView;
        //申明一个新的model
        model = new LoginModelImpl();
    }

    @Override
    public void checkLogin(User user) {
        //保证视图是存在的
        if (view == null){
            return;
        }
        //显示view中的dialog,然后对user信息进行验证
        view.showDialog();
        model.login(user,this);
    }
}

这样我们就实现了将view的事件,通过presenter传递给了model层,让他去处理这一次的检验事件,但是大家有没有发现,我们是将这个事件传递给了model,但是model在处理完了之后,他又怎么将得到的结果通知给presenter呢?因为我们要避免view和model直接接触。所以在这里,我们还需要一个listenter的接口类,让presenter继承这个接口,在传递给model的时候,携带接口一起传过去。然后model通过这个接口告诉presenter,presenter再去通知view。

public interface LoginModelListener {
    void loginSuccess();
    void loginError();
}
public interface LoginModel {
    void login(User user, LoginModelListener listener);
}
public class LoginModelImpl implements LoginModel{
    @Override
    public void login(User user, final LoginModelListener listener) {
        final String name = user.getName();
        final String password = user.getPassword();

        new Handler().postDelayed(new Runnable() {
            @Override
            public void run() {
                Boolean error =false;
                if (TextUtils.isEmpty(name)){
                    error = true;
                    //输入错误
                    System.out.println("输入错误");
                    listener.loginError();
                }
                if (TextUtils.isEmpty(password)){
                    error = true;
                    //输入错误
                    System.out.println("输入错误");
                    listener.loginError();
                }
                if(!error){
                    //登录成功
                    System.out.println("登录成功");
                    listener.loginSuccess();
                }
            }
        },2000);
    }
}

至此,我们就实现了一个简单的MVP的demo,是不是觉得Acitivity里面的逻辑很简单了,看着一下字就轻松了很多。

三、总结

那么我们现在结合刚才的案例。我们再来总结一下。

因为我们要保证view和model直接不能直接通信,所有之间的交互,我们都要通过presenter这一个中间类来进行传递。persenter中拥有view和model的引用,然后,view中有事件产生时,将事件以及需要的参数传给presenter,presenter再交给model,待model处理完了之后,将反馈信息传给presenter,presenter再将返回结果告诉view,最后呈现给用户。

流程图

github代码

相关文章

  • MVP 笔记

    MVP 与 MVC 简单介绍 实践 参考资料:Android MVP 详解(下)一步一步实现 Android 的M...

  • Android MVP框架简单实现

    Android MVP设计架构简单实现,其实就是为了以后编写代码的时候能偷懒。 1. 什么是MVP MVP是相对M...

  • Android MVP的简单实现

    一个好的好的设计模式可以帮我们很好的管理我们的代码,也会方便于我们的后期的扩展。特别是针对我们这样的新手,学好一个...

  • Kotlin Android MVP设计模式及基类的实现

    前言 之前写过一篇文章说的是如何用java实现mvp模式Android MVP模式 简单入门实践现在不是用的Kot...

  • 20151226-App架构以及MVP和MVVM了解

    1.MVP:先模仿照抄,搬运工来啦 一种在android中实现MVP模式的新思路 译文-Android的MVP模式...

  • Android MVP 模式的简单实现

    一、概述 MVP(Model-View-Presenter) 是总所周知MVC模式的一个演变,他们的主要目的都是划...

  • Android MVP

    Android MVP初探 Android MVP进阶 Android MVP高级 Android MVP扩展

  • MVP框架学习

    一、MVP介绍 二、为什么使用MVP模式 三、MVP与MVC的异同 四、使用MVP实现Android的登录的Dem...

  • MVP

    本文是对Android MVP 的简单介绍与使用的学习笔记,对着博客实现了相应代码。 一、作用 Model-Vie...

  • Android Mvp实践

    Android Mvp实践 简介 本文是参考google官方发布的MVP架构demo以及前人对MVP实现方式的一些...

网友评论

      本文标题:Android MVP的简单实现

      本文链接:https://www.haomeiwen.com/subject/djaebxtx.html