Mvp模式的进一步探索

来源:互联网 发布:macrar解压软件下载 编辑:程序博客网 时间:2024/05/16 17:45

对于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
原创粉丝点击