Mvp模式的进一步探索

对于MVC模式的熟悉以及先入为主的观念造成我对MVP的写法内心深处多少有些抵触,毕竟还是理智的,相信群众的眼镜是雪亮的,大家觉得MVP比MVC好那就是真的好;这不在朋友的帮助下,我也逐渐接受和理解了MVP的一些道道,再加上相信大家对于MVC模式下的代码维护和重构,版本跟新时对繁琐的逻辑感到无比的厌烦吧,那好,今天就将我的一点粗浅的认知说出来请大家指正,大牛请绕行。。。

这里拿一个简单的登录案例来写个例子来看看MVP的影子吧:

就是这样一个简单的布局:
这里写图片描述

首先来看Moudle:

public class User {

    private String name;
    private String password;
    private boolean remPsw;
    private boolean autoLogin;

    //...省略构造方法以及get和set方法
}

然后我们来看一下View和Presenter的Base接口(写Base相信已经是大家一个很好的习惯了,如果你还没有养成这样的习惯建议你…你懂得!)

public interface IBasePresenter {

    void start();

}

public interface IBaseView<T> {

    void setPresenter(T presenter);
}

这没啥好说的Base接口主要是用来继承的,而这个View接口的 setPresenter方法接受一个Presenter对象作为参数,从方法名不难看出这个方法是给View设置对应的Presenter,具体怎么实现的?等会我们来看看View里面是怎么实现这个方法的…

接下来看一下View和Presenter接口(由 于View和Presenter总是一一对应的关系,所以将他们写在同一接口,这样既方便管理又减少很多命名的繁琐过程)

public interface LoginContract {

    interface View extends IBaseView<Presenter>{

        void showLoginSuccess();//登录成功的展示或者页面跳转
        void showOverLogin();//已经登录过的用户可以跳过登录界面
        void showErrorToast();//用户账号和密码输入错误是的Toast提示
        User getUserInfo();//获得当前用户对象

    }

    interface Presenter extends IBasePresenter{

        void loginOrNot(User user);//判断用户登录成功

        void overLogin();//判断是否略过登录界面

    }

}

上述方法已经添加注释这里就不多解释了…

进行下一步,来看看集中逻辑判断代码的Presenter类吧

public class MvpActivityPresenter implements LoginContract.Presenter {

    private Context context;
    private LoginContract.View view;

    public MvpActivityPresenter(Context context, LoginContract.View view) {
        this.context = context;
        this.view = view;
        view.setPresenter(this);
    }


    @Override
    public void overLogin() {
        SharedPreferences sharedPreferences = context.getSharedPreferences("user_info", Context.MODE_PRIVATE);
        //可以获取用户信息直接传递给下个页面
//        String name = sharedPreferences.getString("name", "");
//        int age = sharedPreferences.getInt("age", 0);
        boolean isLogined=sharedPreferences.getBoolean("islogined",false);
        if (isLogined){
           view.showOverLogin();
        }

    }

    @Override
    public void loginOrNot(User user) {
        if (checkAccountAndPassword(user.getName(), user.getPassword())) {
            postOrSave(user);//保存数据
            view.showLoginSuccess();
        }else {
            view.showErrorToast();
        }

    }




    /**
     * 请求服务器验证账号或者密码是否正确,或进行本地验证
     *
     * @return
     */
    public boolean checkAccountAndPassword(String name, String password) {

        if (name.equals("Jack") && password.equals("123456")) {
            return true;
        }
        if ((name == "Jack") && (password == "123456")) {
            return true;
        }

        return false;
    }


    /**
     * 本地保存或者发送给服务器
     */
    public void postOrSave(User user) {

        SharedPreferences sharedPreferences = context.getSharedPreferences("user_info", Context.MODE_PRIVATE);
        SharedPreferences.Editor editor = sharedPreferences.edit();//获取编辑器
        editor.putString("name", user.getName());
        editor.putString("password", user.getPassword());
        editor.putBoolean("rempassord", user.isRemPsw());
        editor.putBoolean("autologin", user.isAutoLogin());
        editor.putBoolean("islogined", true);
        editor.commit();//提交修改

    }

    @Override
    public void start() {

    }
}

注意这里实现的是LoginContract的Presenter接口,所以必须要实现里面所有的方法,后面又添加了保存数据和判断账号密码是否正确的方法,另外注意看里面的两个成员变量:ContextLoginContract的View接口 , 而在构造方法中调用view.setPresenter(this)给View对象设置了当前Prensenter(而后在View中将其实例化…..这里说的对不对,我们在View中见分晓…),所以这个Presenter可以调用LoginContract的View接口里面的方法 , 而View又实现了View接口 , 所以这个Presenter可以在在进行逻辑判断的同时间接与用户交互,也就是说Presenter是通过View接口与View交互的 ,同时在Prenseter中对User进行了操作 , 所以Presenter和Moudle是可以直接交互的 .

好,接下了我们来看一下在MVC中无比强大的View吧:

public class MvpActivity extends AppCompatActivity implements LoginContract.View{

    EditText etAccent,etPassword;
    CheckBox cbRemPassword,cbAutoLogin;
    Button btnLogin ;

    private LoginContract.Presenter presenter;

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        new MvpActivityPresenter(this,this);
        presenter.overLogin();
        initView();
        getUserData();

    }

    /**
     * 初始化View
     */
    private void initView() {
        etAccent= (EditText) findViewById(R.id.loginName);
        etPassword= (EditText) findViewById(R.id.password);
        cbRemPassword= (CheckBox) findViewById(R.id.savePwd);
        cbAutoLogin= (CheckBox) findViewById(R.id.openStart);
        btnLogin= (Button) findViewById(R.id.btnLogin);
    }

    /**
     * 拿到用户的输入和设置数据
     */
    private void getUserData() {

        btnLogin.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {


                presenter.loginOrNot(getUser());

            }
        });


    }



    @Override
    public void setPresenter(LoginContract.Presenter presenter) {
        this.presenter=presenter;
    }




    @Override
    public void showLoginSuccess() {
        Toast.makeText(MvpActivity.this, "登录成功", Toast.LENGTH_SHORT).show();
        //dialog的dismiss
        //startActivity(new Intent(MvpActivity.this,...));
    }

    @Override
    public void showOverLogin() {
        Toast.makeText(MvpActivity.this, "已登录", Toast.LENGTH_SHORT).show();
    }

    @Override
    public void showErrorToast() {
        Toast.makeText(MvpActivity.this, "账号或密码有误", Toast.LENGTH_SHORT).show();
    }

    @Override
    public User getUserInfo() {
        String userName=etAccent.getText().toString().trim();
        String userPassword=etPassword.getText().toString().trim();
        boolean remPassword=cbRemPassword.isChecked();
        boolean autoLogin=cbAutoLogin.isChecked();

        return new User(userName,userPassword,remPassword,autoLogin);
    }


}

仔细看看这个Activity里面的代码,是不是很轻松,里面就做了控件初始化,点击事件的监听和数据的获得等于用户交互的代码;
下面我们来仔细看看这个类,它实现了LoginContract里的View接口,并创建了LoginContract里的Presenter接口对象,并调用接口里面的方法来进行逻辑判断,这样就形成了一个Presenter和View个性独特并且相互合作来完成了登录的实现逻辑;

这就好比有一个逻辑思维严密 , 而性格不张扬低调的理工男—-Presenter爱上了十分漂亮情商特别高的交际花—–View,当二人四目相对,一见钟情,电光石火,然后掏出了各自的爱的秘钥—–Interface , 然后各取所需 , 完美结合 , 你中有我 , 我中有你 , 从此一发不可收拾… !
写出这样一场感人至深,荡气回肠的爱情故事人却不是我们的琼瑶阿姨 , 而是大家的MVP!!!

注: 前面所说的接口笔者指的是手,所有想歪的程序员,到墙角蹲着去………

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值