MVP模式在项目中的使用

来源:互联网 发布:下载刷赞软件 编辑:程序博客网 时间:2024/06/15 18:35

1.MVP模式的简介:

相对于mvc,mvp模式中p就是presenter的缩写,意思相当于主持人,它协调view和model的连接,view和model相当于是两个不认识的人,他们中间的中介就是presenter,p持有m和v两个的联系方式。view要处理页面就要要数据,就去找p,让p去拿数据。而p呢就会直接找m去要数据,m把数据给p,然后p拿着数据进行加工,然后给v有用的数据,来用于v的展示。这个过程很像我们通过中介找房子。中介有我们和出租房的联系方式,可以通过查询系统,获取到出租房的房源信息,然后给我们最后有用的信息,比如房屋价格,环境等。但是我们是和房东没有办法直接联系的。这就是mvp。而mvc的话v是可以持有model数据的,这就导致v可能会对model做数据修改。导致会掺杂一些业务逻辑。使得业务逻辑在m和c以及v中混杂到一起。这个典型的例子就是activity。既要控制显示,还要管理数据。非常混乱。而为了更好的分层,还有后续如果我换v和m都没有很大影响的话,我们就延伸出了mvp。就如那个中介,它可以换一套查询系统和房东信息,也可以换租户,但是实现的模式还是不变的。


2.MVP模式具体使用方法:

在项目中的使用:

我们通常需要以接口的形式来实现三者的关系,这样方便后续的扩展。

以登陆为例:

Model:

/**
 * 描述:登录界面请求接口
 *  */public interface LoginInteractor extends MvpInteractor {    /**     * 登录     * @param phone     * @param pwd     * @param loginInteractorListener     */    void userLogin(String phone, String pwd, LoginInteractorListener loginInteractorListener);    /**     * 请求接口监听器     */    interface LoginInteractorListener {        /**         * 请求成功且业务代码 也成功         */        void succeed();        /**         * 请求成功,但是业务代码失败         * @param message         */        void failed(String message);        /**         * 请求失败         *         * @param error         */        void connectFail(String error);         }}


View:

/** * 描述: * 作者:58 on 2016/5/11 10:41 */public interface LoginView extends MvpView {    /**     * 登录成功view显示     */    void loginSucceed();    /**     * 登录失败view显示     * @param message     */    void loginFailed(String message);
    void showNotice(String message);

    void showNotice(String message);
    /**     
    * 返回当前登录界面btn的状态 
    * @param canClick  
   */  
   void isCanClick(boolean canClick);
    void loadingDismiss();
}


Presenter:

/**
 * 描述:登录界面逻辑控制器 */public interface LoginPresenter extends MvpPresenter<LoginView> {    /**     * 登录     * @param phone     * @param pwd     */    void login(String phone, String pwd, String validcode);    /**     * 检测是否可以点击登录btn     * @param userPhone     * @param password     */    void checkClickBtn(String userPhone, String password);}

public interface MvpPresenter<T extends MvpView> {
    /**     * 将MVP的View附加到Presenter     */    void attachView(T view);        void attachView(T view,ViewGroup rootView);    void detachView();}

具体的实现类如下:

/**
 * 描述:登录界面逻辑控制器实现 */public class LoginPresenterImpl implements LoginPresenter, LoginInteractor.LoginInteractorListener, GetPictureVerCodeInteractor.GetPictureVerCodeInteractorListener {    private LoginView mLoginView;    private Context mContext;    private LoginInteractor mLoginInteractor;    public LoginPresenterImpl(Context context) {        mContext = context;        mAccount = Account.getAccount(mContext);    }    @Override    public void attachView(LoginView view) {        mLoginView = view;        mLoginInteractor = new LoginInteractorImpl(mContext);    }    @Override    public void attachView(LoginView view, ViewGroup rootView) {    }    @Override    public void detachView() {        mLoginInteractor.cancelAllRequest();        mContext = null;        mLoginView = null;    }    @Override    public void login(String phone, String pwd, String validcode) {        mLoginInteractor.userLogin(phone, pwd, this);    }    @Override    public void checkClickBtn(String userPhone, String password) {        boolean canClick = !userPhone.isEmpty() && userPhone.length() == 11 && !password.isEmpty() && password.length() >= 6;        mLoginView.isCanClick(canClick);    }    @Override    public void succeed() {        mLoginInteractor.sendPPU(this);    }    @Override    public void failed(String message) {        mLoginView.loginFailed(message);    }    @Override    public void connectFail(String error) {        mLoginView.showNotice(error);    }    @Override    public void requestFinish() {        mLoginView.loadingDismiss();    }}
Model:

/**
 * 描述:登录界面请求接口实现类 */public class LoginInteractorImpl implements LoginInteractor {    public Context mContext;    public LoginInteractorImpl(Context context) {        mContext = context;    }    @Override    public void cancelRequest(String requestTag) {        HttpManager.getHttpManagerBase(mContext).cancelRequest(requestTag);    }    @Override    public void cancelAllRequest() {        HttpManager.getHttpManagerBase(mContext).cancelRequest(ConstantConfig.LOGIN_TAG);        mContext = null;    }    @Override    public void userLogin(final String phone, final String pwd, final String validcode, final String vcodekey, final LoginInteractorListener loginInteractorListener) {        final Map<String, String> map = setParams(phone, pwd, validcode, vcodekey);        LogUtil.i("userlogin", map.toString());        String url = "http://test/login;   //这里只做示例        HttpManager.getHttpManagerBase(mContext).httpPost(url, map, ConstantConfig.LOGIN_TAG, new RequestResultListener() {            @Override            public void onSuccess(String info, Object tag) {                Log.e("--------------", info);                Gson gson = new Gson();                LoginInfo loginInfo = gson.fromJson(info, LoginInfo.class);                if (loginInfo != null) {                    loginInteractorListener.succeed();                }                loginInteractorListener.requestFinish();            }            @Override            public void onFail(String code, String msg, String info, Object tag) {                              loginInteractorListener.failed(msg);                              loginInteractorListener.requestFinish();            }            @Override            public void connectFail(NetworkResponse error, Object tag) {                LogUtil.i("wuba", "connectFail");                loginInteractorListener.connectFail("网络异常请重试");                loginInteractorListener.requestFinish();            }        });    }   }

我们可以让我们的Activity实现View的接口即可。如下

public class LoginActivity extends BaseActivity implements LoginView {
     。。。。。此处隐去1000字大笑public void loginSucceed() {    ToastUtil.show(this, "登录成功");    if (mDialog != null) {        dialogIsShow = false;        mDialog.dismiss();    }    loginIntent();}@Overridepublic void loginFailed(String message) {    if (mDialog != null) {        mDialog.dismiss();        dialogIsShow = false;    }    if (TextUtils.isEmpty(message)) {        message = "登陆异常,请稍后重试!";    }    ToastUtil.show(this, message);}@Overridepublic void showNotice(String message) {    ToastUtil.show(this, message);}@Overridepublic void isCanClick(boolean canClick) {    if (canClick) {        loginLoginButton.setBackgroundResource(R.drawable.wb_login_btn_xml);        loginLoginButton.setClickable(canClick);    } else {        loginLoginButton.setBackgroundResource(R.drawable.wb_unlogin_btn_xml);        loginLoginButton.setClickable(canClick);    }}@Overridepublic void loadingDismiss() {    qianguiAccountLoading.statusToNormal();    qianguiAccountLoading.setVisibility(View.GONE);}
@Override
}
以上的代码中删去了一部分和公司相关的字段和数据,只是给大家做一个示例,不要生搬硬套。v和m的书写完全看个人的业务需求。

当我们需要替换登陆页面,或者需要替换登陆方式时,这时就会发现我们只需要动View和model即可。p就可以完全保持不动。

如果大家有什么不理解的地方,也可以给我留言。

1 0
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 六棱螺丝滑丝了怎么办 苹果6螺丝滑牙了怎么办 外六角螺丝圆了怎么办 小螺丝拧花了怎么办 老人退伍证丢了怎么办 狗狗又拉又吐怎么办 孕妇吃了马兰头怎么办 怀孕吃了马兰头怎么办 吃了茭白和豆腐怎么办 电气焊加工怎么办环评 手上皮肤干燥起皮怎么办 脸上起皮怎么办还痒痒 店铺4周被释放了怎么办 炫舞账号忘了怎么办 椎基底供血不足怎么办? 脑动脉供血不足怎么办 颈椎引起的脑供血不足怎么办 军人保障卡怎么办假的 正常形态精子率低怎么办 前向运动精子21怎么办 前向运动精子22%怎么办 前向运动精子19%怎么办 前向运动精子为0怎么办 被蝎子草扎了怎么办 二年级孩子成绩差怎么办 长治医保卡丢了怎么办 农商银行倒闭钱怎么办 2相电变3相电怎么办 电机六根线乱了怎么办 三相电零线带电怎么办 孕30周胎盘偏厚怎么办 偏侧咀嚼大小脸怎么办 咀嚼导致的脸歪怎么办 30岁了不想长大怎么办 4岁宝宝沉迷手机怎么办 我沉迷于了游戏怎么办 学生小红本丢了怎么办 小学玩6年初中怎么办 鼻炎喘不过来气怎么办 面对素质低的人怎么办 对没素质的人怎么办