MVP模式重用性的一些思考
2017-01-18 18:09
323 查看
一,概述
![](http://img.blog.csdn.net/20170118182655262?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvYWJjY2pm/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast)
如上图看起来很好理解,其中View中包含了Presenter,Presenter中有View的接口和Model,可以调用View和Model。Model可以说完全独立。MVP与MVC的区别:在MVP中View并不直接使用Model,它们之间的通信是通过Presenter 来进行的,所有的业务逻辑都在Presenter,而在MVC中View会直接从Model中读取数据而不是通过 Controller。
MVP优点:
1、对MVC进一步解耦,model与view完全分离
2、单元测试,因逻辑都在Presenter,presenter的逻辑就可以方便单元测试,还有Model也很好测试
3、重用性,我们可以把Presenter用于不同的view上,还有Model更加可以独立使用
二,示例
下面模式是参考google的todoapp mvp示例
1,接口封装
2,Model
3,View
4,Presenter
三,一些思考
现在要加多一个功能,手机登录当然要获取验证码,而找回密码也要获取手机验证码,一般会写成同一个接口不同参数,这样我们的Model,View和Presenter怎么处理呢。
我看过不少人会Presenter是和界面挂钩,其中包括我以前也这样。若他们分工是A做登录,B做找回密码,他们可能会弄了一个LoginPresenter(有获取验证码的处理和有登录的处理)和一个ForgotPwdPresenter(有获取验证码的处理和有提交找回密码的处理),相应的View实现的功能也会实现一套一样的,Model估计倒不会再加一个。这样重用性明显少了点,model可以重用,presenter却不能重用了。那我们的Presenter不能和界面挂钩应该和model挂钩才对,一个界面应该允许多个不同功能逻辑的presenter,View可以实现多个View接口。下面上代码:
1,VerificationCodeContract
2,VerificationCodeService
3,VerificationCodePresenter
4,LoginActivity
这样LoginPresenter和VerificationCodePresenter都可以重用,用在不同的东西,还有service肯定也可以的,也便于单元测试
如上图看起来很好理解,其中View中包含了Presenter,Presenter中有View的接口和Model,可以调用View和Model。Model可以说完全独立。MVP与MVC的区别:在MVP中View并不直接使用Model,它们之间的通信是通过Presenter 来进行的,所有的业务逻辑都在Presenter,而在MVC中View会直接从Model中读取数据而不是通过 Controller。
MVP优点:
1、对MVC进一步解耦,model与view完全分离
2、单元测试,因逻辑都在Presenter,presenter的逻辑就可以方便单元测试,还有Model也很好测试
3、重用性,我们可以把Presenter用于不同的view上,还有Model更加可以独立使用
二,示例
下面模式是参考google的todoapp mvp示例
1,接口封装
package com.jerrycai.mymvp.login; import com.jerrycai.mymvp.base.IView; import com.jerrycai.mymvp.bean.User; /** * Created by JerryCai on 2017/1/18. */ public interface LoginContract { interface View extends IView { void loginSuccess(User user); void loginFailure(String code, String msg); } interface Presenter { void login(String phone, String pwd); } }
2,Model
package com.jerrycai.mymvp.service; import com.jerrycai.mymvp.callback.Callback; /** * Created by JerryCai on 2017/1/18. */ public class UserService { public void login(String phone, String pwd, Callback callback) { //连网处理 } }
3,View
package com.jerrycai.mymvp.login; import android.app.Activity; import android.os.Bundle; import com.jerrycai.mymvp.bean.User; /** * Created by JerryCai on 2017/1/18. */ public class LoginActivity extends Activity implements LoginContract.View { private LoginContract.Presenter mPresenter; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); mPresenter = new LoginPresenter(this); mPresenter.login("test","test"); } @Override public void loginSuccess(User user) { //成功处理 } @Override public void loginFailure(String code, String msg) { //失败处理 } }
4,Presenter
package com.jerrycai.mymvp.login; import com.jerrycai.mymvp.base.BasePresenter; import com.jerrycai.mymvp.bean.User; import com.jerrycai.mymvp.callback.Callback; import com.jerrycai.mymvp.service.UserService; /** * Created by JerryCai on 2017/1/18. */ public class LoginPresenter extends BasePresenter<UserService, LoginContract.View> implements LoginContract.Presenter { public LoginPresenter(LoginContract.View view) { super(new UserService(), view); } @Override public void login(String phone, String pwd) { mMoudel.login(phone, pwd, new Callback<User>() { @Override public void onSuccess(User user) { mView.loginSuccess(user); } @Override public void Failure(String code, String msg) { mView.loginFailure(code, msg); } }); } }
三,一些思考
现在要加多一个功能,手机登录当然要获取验证码,而找回密码也要获取手机验证码,一般会写成同一个接口不同参数,这样我们的Model,View和Presenter怎么处理呢。
我看过不少人会Presenter是和界面挂钩,其中包括我以前也这样。若他们分工是A做登录,B做找回密码,他们可能会弄了一个LoginPresenter(有获取验证码的处理和有登录的处理)和一个ForgotPwdPresenter(有获取验证码的处理和有提交找回密码的处理),相应的View实现的功能也会实现一套一样的,Model估计倒不会再加一个。这样重用性明显少了点,model可以重用,presenter却不能重用了。那我们的Presenter不能和界面挂钩应该和model挂钩才对,一个界面应该允许多个不同功能逻辑的presenter,View可以实现多个View接口。下面上代码:
1,VerificationCodeContract
package com.jerrycai.mymvp.contract; import com.jerrycai.mymvp.base.IView; /** * Created by JerryCai on 2017/1/18. */ public interface VerificationCodeContract { interface View extends IView { void onCodeCallback(boolean success, String errorMsg); } interface Presenter { void getCode(String phone, int type); } }
2,VerificationCodeService
package com.jerrycai.mymvp.service; import com.jerrycai.mymvp.callback.Callback; /** * Created by JerryCai on 2017/1/18. */ public class VerificationCodeService { public void getCode(String phone, int type, Callback callback) { //连网处理 } }
3,VerificationCodePresenter
package com.jerrycai.mymvp.presenter; import com.jerrycai.mymvp.base.BasePresenter; import com.jerrycai.mymvp.callback.Callback; import com.jerrycai.mymvp.contract.VerificationCodeContract; import com.jerrycai.mymvp.service.VerificationCodeService; /** * Created by JerryCai on 2017/1/18. */ public class VerificationCodePresenter extends BasePresenter<VerificationCodeService, VerificationCodeContract.View> implements VerificationCodeContract.Presenter { public VerificationCodePresenter(VerificationCodeContract.View view) { super(new VerificationCodeService(), view); } @Override public void getCode(String phone, int type) { mMoudel.getCode(phone, type, new Callback() { @Override public void onSuccess(Object o) { mView.onCodeCallback(true, null); } @Override public void Failure(String code, String msg) { mView.onCodeCallback(false, msg); } }); } }
4,LoginActivity
package com.jerrycai.mymvp.login; import android.app.Activity; import android.os.Bundle; import com.jerrycai.mymvp.bean.User; import com.jerrycai.mymvp.contract.LoginContract; import com.jerrycai.mymvp.contract.VerificationCodeContract; import com.jerrycai.mymvp.presenter.LoginPresenter; import com.jerrycai.mymvp.presenter.VerificationCodePresenter; /** * Created by JerryCai on 2017/1/18. */ public class LoginActivity extends Activity implements LoginContract.View,VerificationCodeContract.View { private LoginContract.Presenter mPresenter; private VerificationCodeContract.Presenter mCodePresenter; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); //-------------示范用的,直接写在这样而已 mPresenter = new LoginPresenter(this); mPresenter.login("test","test"); mCodePresenter = new VerificationCodePresenter(this); mCodePresenter.getCode("test",0); } @Override public void loginSuccess(User user) { //成功处理 } @Override public void loginFailure(String code, String msg) { //失败处理 } @Override public void onCodeCallback(boolean success, String errorMsg) { //处理验证码 } }
这样LoginPresenter和VerificationCodePresenter都可以重用,用在不同的东西,还有service肯定也可以的,也便于单元测试
相关文章推荐
- 使用C++实现JNI接口需要注意的事项
- Android IPC进程间通讯机制
- Android Manifest 用法
- [转载]Activity中ConfigChanges属性的用法
- Android之获取手机上的图片和视频缩略图thumbnails
- Android之使用Http协议实现文件上传功能
- Android学习笔记(二九):嵌入浏览器
- android string.xml文件中的整型和string型代替
- i-jetty环境搭配与编译
- android之定时器AlarmManager
- android wifi 无线调试
- Android Native 绘图方法
- Android java 与 javascript互访(相互调用)的方法例子
- android 代码实现控件之间的间距
- android FragmentPagerAdapter的“标准”配置
- Android"解决"onTouch和onClick的冲突问题
- android:installLocation简析
- android searchView的关闭事件