Android Mvp初探体验

Android Mvp初探体验

MVP的架构概念已经出现很长时间了,但是小的一直没有实际的应用的项目中,最近找到了新工作,头儿要求我们新项目必须采用mvp架构,并且要出一份架构设计文档,所以小的赶紧研究起来,正好与大家一起分享。

转载请注明出处,虽然也不会有人转```

mvp已经出现很久相信大家其实已经对mvp有了一些了解,所以我也就不贴一些非常专业的但是一下子看不懂的图了,mvp的原理其实用一句话概括的话就是:把所有的逻辑都放在presenter层里

传统的mvc模式大家共同的认识基本上是xml布局是v,activity是c,这就导致了activity非常的臃肿,有的比较复杂的activity设置多达上千,几千行的也有,导致臃肿的原因,其实是xml布局不能完全的满足我们对布局的需求,非常多的时候我都需要在activity写逻辑的同时又要写布局相关的代码。

然后大牛们发现了这个问题,咋解决呢,很简单就是在拿出一个presenter层来专门处理逻辑,activity你不是没事儿就爱弄弄布局,摆弄摆弄控件吗?自己玩去吧,so:
原来是:
我们以为activity是c其实activity又是c又是v:
mvc的本质
但是mvp被提出以后,直接暴露了activity的本质,activity你就是v,别在这装了,我们找了帅小伙小p替代你,老老实实做的v吧,所以变成了这样:MVP的思想
这篇乱码七糟,瞎扯犊子博文写到这儿相信各位懂的都当笑话看了,没懂的还是没懂,so,我还有代码啊,哈哈,这你敢信。
我们用传统的mvc的方式做一个,登录页面,有清空输入框,有登陆然后本地做个延时模拟一下网络连接,showtime:
这是布局文件:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/activity_main"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    android:orientation="vertical"
    tools:context="com.ly.mvclogindemo.MainActivity">

    <ProgressBar
        android:id="@+id/progress"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center_horizontal"
        android:visibility="gone"
        />
    <EditText
        android:id="@+id/et_username"
        android:layout_width="match_parent"
        android:layout_height="50dp"
        android:hint="请输入用户名"
      />
    <EditText
        android:id="@+id/et_pass"
        android:layout_width="match_parent"
        android:layout_height="50dp"
        android:hint="请输入密码"
        />

    <Button
        android:id="@+id/btn_login"
        android:layout_width="match_parent"
        android:layout_height="50dp"
        android:text="登录"
        />
    <Button
        android:id="@+id/btn_clear"
        android:layout_width="match_parent"
        android:layout_height="50dp"
        android:text="清空"
        />

</LinearLayout>

so easy的一个布局文件两个输入框俩按钮一个progress,没啥说的
下面是mvc的代码:

package com.ly.mvclogindemo;

import android.os.Handler;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.text.TextUtils;
import android.view.View;
import android.widget.EditText;
import android.widget.ProgressBar;
import android.widget.Toast;

public class MainActivity extends AppCompatActivity {
    EditText et_username,et_pass;
    ProgressBar pbar;
    Handler handler;

{
    handler = new Handler();
}
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        init();
    }

    private void init(){
        et_username = (EditText) findViewById(R.id.et_username);
        et_pass = (EditText) findViewById(R.id.et_pass);
        pbar = (ProgressBar) findViewById(R.id.progress);
        findViewById(R.id.btn_clear).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                et_username.setText("");
                et_pass.setText("");
            }
        });
        findViewById(R.id.btn_login).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                pbar.setVisibility(View.VISIBLE);
                String user = et_username.getText()+"";
                String pass = et_pass.getText()+"";
                if (!TextUtils.isEmpty(user) && user.equals("ly") && !TextUtils.isEmpty(pass) && pass.equals("123")) {
                    handler.postDelayed(new Runnable() {
                        @Override
                        public void run() {
                            pbar.setVisibility(View.GONE);
                            Toast.makeText(MainActivity.this,"登录成功",Toast.LENGTH_SHORT).show();
                        }
                    }, 1000);
                }else{
                    handler.postDelayed(new Runnable() {
                        @Override
                        public void run() {
                            pbar.setVisibility(View.GONE);
                            Toast.makeText(MainActivity.this,"登录失败",Toast.LENGTH_SHORT).show();

                        }
                    },1000);
                }
            }
        });
    }

}

这么简单的一个页面这么简单的逻辑和需求,相信很多同学都像我这样写一下就ok了,代码习惯比较好的同学可能会多搞出几个方法,做做优化基本也就那样,最后就是做完就是一个xml一个activity可能还有一个userBean这里我没写也没贴,userbean大家都懂(getUserName(),setUserName(),全是这玩意),可以看出来代码是稍微有点乱的,不排除我奔来写的就乱,但是相信很多同学在面对非常简单的需求的时候,在加上比较忙可能也会像我这样写一下。
然后来看mvp:
1,MVP的类会增加很多所以,我先贴一下目录
这里写图片描述
可以看出来多了很多类,具体都多了哪些呢,LoginViewInter,LoginPresenterInter,ILoginPresenter,以Base开头的类请大家自动无视一下3q。
我们逐个讲解一下:
1.首先讲解一下,我们发现多了好多接口,这些接口是干什么的,显然我们希望用接口实现m,v,p各层之间的通信,或者说联系,这样还不用暴露具体的实现。
2。LoginViewInter这个就是v的接口当然是由activity来实现它:

package com.ly.demo.view;

/**
 * Created by txw_pc on 16/11/17.
 */

public interface LoginViewInter {


    void clearUserAndPass();
    void login();
    void loginSucceed();
    void loginFailed();
    String getUsername();
    String getPass();
}

非常简单,定义了activity所有有关ui的可能出先的操作,但是也只限于有关ui的,那个login是指的点登陆按钮时ui的变化```
实现了这个接口的activity:

package com.ly.demo;

import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ProgressBar;
import android.widget.Toast;

import com.ly.demo.presenter.ILoginPersenter;
import com.ly.demo.view.LoginViewInter;

public class MainActivity extends BaseActivity implements LoginViewInter{

    Button  clearbtn,loginbtn;
    EditText username_et,pass_et;
    ProgressBar pbar;
    ILoginPersenter iLoginPersenter;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_login);
        iLoginPersenter = new ILoginPersenter(this);
        initView();

}

    private void initView(){
        clearbtn = (Button) findViewById(R.id.login_clear_btn);
        loginbtn = (Button) findViewById(R.id.email_sign_in_button);
        username_et = (EditText) findViewById(R.id.login_username_et);
        pass_et = (EditText) findViewById(R.id.login_pass_et);
        pbar = (ProgressBar) findViewById(R.id.login_progress);
        clearbtn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                iLoginPersenter.clear();
            }
        });
        loginbtn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                iLoginPersenter.login();
            }
        });
    }

    @Override
    public void clearUserAndPass() {
        username_et.setText("");
        pass_et.setText("");
    }

    @Override
    public void login() {
        pbar.setVisibility(View.VISIBLE);
    }

    @Override
    public void loginSucceed() {
        pbar.setVisibility(View.GONE);
        Toast.makeText(this, "登录成功", Toast.LENGTH_SHORT).show();
    }

    @Override
    public void loginFailed() {
        pbar.setVisibility(View.GONE);
        Toast.makeText(this, "登录失败", Toast.LENGTH_SHORT).show();
    }

    @Override
    public String getUsername() {
        return username_et.getText()+"";
    }

    @Override
    public String getPass() {
        return pass_et.getText()+"";
    }


}

可以看出来感觉这个类变长了```但是也能感觉出来一下子就变的简单清晰了(没错mvc写那么乱就是为了对比 嘿嘿),我觉得这个也是mvp这么受推崇的原因之一就是可以让比较新手的同学,专注于方法的实现,而不是其它乱码七糟的东西

接着来搞这个LoginPresenterInter,有了之前的LoginViewInter这个应该就不难理解了,这个是presenter的接口,用来定义presenter会用到的逻辑,上代码:

package com.ly.demo.presenter;

/**
 * Created by txw_pc on 16/11/17.
 */

public interface LoginPresenterInter {


    void login();
    void clear();

}

简单到变态```就一个登陆的逻辑和一个清除输入框内容的逻辑简直不知道该说啥 我擦
接着来看他的实现类ILoginPresenter

package com.ly.demo.presenter;

import android.os.Handler;
import android.text.TextUtils;

import com.ly.demo.view.LoginViewInter;

/**
 * Created by ly on 16/11/17.
 * login逻辑
 */

public class ILoginPersenter extends BasePresenter implements LoginPresenterInter {
    User user;
    private LoginViewInter loginViewInter;

    private Handler handler;

    {
        handler = new Handler();
        user = new UserBean;
    }

    public ILoginPersenter(LoginViewInter loginview) {
        this.loginViewInter = loginview;
    }

    @Override
    public void login() {
        loginViewInter.login();
        String user = loginViewInter.getUsername();
        String pass = loginViewInter.getPass();
        user.setUserName(user);
        user.setPass(pass);
        if (!TextUtils.isEmpty(user) && user.equals("ly") && !TextUtils.isEmpty(pass) && pass.equals("123")) {
            handler.postDelayed(new Runnable() {
                @Override
                public void run() {
                    loginViewInter.loginSucceed();
                }
            }, 1000);
        }else{
            handler.postDelayed(new Runnable() {
                @Override
                public void run() {
                    loginViewInter.loginFailed();
                }
            },1000);
        }
    }

    @Override
    public void clear() {
        user.setUserName("");
        user.setPass("");
        loginViewInter.clearUserAndPass();
    }
}

可以看出来就是模拟了一下网络 然后做了一下判断,没有了,看上去也很简单。
代码贴完了,总结一下,mvp的方式做出来的程序确实是,肯上去可读性很好,而且很清晰,还可以帮助同学们专注于功能的开发上,避免逻辑和ui逻辑进行混杂。但是也有缺点,那就是会多出来很多的接口和类,而且用接口来回沟通的方式实话确实很不错,但是也有弊端,我感觉这样写的比较多的时候很容易因为来回改接口来回跳类而逻辑混乱(我感觉我会那样```,毕竟脑袋有点笨),但是较大型的项目使用mvp就可以很好的进行约束了,同样如果太小的项目也感觉没有必要这样搞,但是仁者见仁智者见智,说实话我自己写了一次感觉还真是挺好的。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值