JessYanCoding / JessYanCoding/MVPArms
实际开发中对 MVP 使用上的优化
- Dominant language
- Java
- Stars
- 10.2k
- Forks
- 2.3k
- PR merge metrics
- No merged PRs in 30d
Description
在使用框架过程中碰到 mvp 架构需创建文件数量庞问题,可能我的做法不正确,特请教下如何优化?
希望大佬能增加 DEMO 功能,提供多功能下如何设计和组织代码,为大家提供参考。以下是我的一些设计疑问,也贴出了源码希望和大家一起探讨如何设计。
比如用户模块下有以下功能
- 登录
- 注册
由于两个页面的 UI 、逻辑、网络请求都不一样,所以普通的做法是单独为每个功能创建 XXXActivity、XXXPresenter、创建 Contract 协议类、创建Model,比如一个登录功能就要创建四个文件吗?注册功能又要创建 4 个文件,意味着每个小功能都要创建 4 个文件,带来的问题是文件数量太过于庞大了,所以我想问有什么好的方案优化,你们是怎么处理的?
我的优化:
##### 优化了协议类。不为每个功能创建 XXXContract ,由于我的是组件化工程,每个子工程下公用一个 Contract, 用内部类区分每个功能协议,这样减少了协议类的创建,比如用户模块
代码大致这样子:
```ruby
public class UserContract {
//--------- 微信授权 ----------
public interface WxAuthView extends IView {
}
public interface WxAuthModel extends IModel {
Observable getLoginInfo(Map reqMap);
}
//--------- 绑定手机 ----------
public interface BindPhoneView extends IView {
void enableVerificationCodeBtn(boolean enable);
void setVerificationCodeText(String verificationCodeText);
}
public interface BindPhoneModel extends IModel {
Observable getVerificationCode(Map reqMap);
Observable putBindPhoneNumber(Map reqMap);
}
//--------- 选择区号 ----------
public interface AreaCodeView extends IView {
void showAreaCodeList(List areaCodeBeanList);
void onNetWorkError(String errorMsg);
}
public interface AreaCodeModel extends IModel {
Observable getAreaCodeList(Map reqMap);
}
//--------- 登录 ----------
public interface LoginView extends IView {
void enableVerificationCodeBtn(boolean enable);
void setVerificationCodeText(String verificationCodeText);
void llCodeVisible(boolean visible, int loginType);
}
public interface LoginModel extends IModel {
Observable getVerificationCode(Map reqMap);
Observable getLoginInfo(Map reqMap);
}
//--------- 找回密码 ----------
public interface FindPasswordView extends IView {
void enableVerificationCodeBtn(boolean enable);
void setVerificationCodeText(String verificationCodeText);
}
public interface FindPasswordModel extends IModel {
Observable getVerificationCode(Map reqMap);
Observable putResetPassword(Map reqMap);
}
//--------- 预填资料 ----------
public interface PrepareInfoView extends IView {
}
public interface PrepareInfoModel extends IModel {
Observable postPrepareInfo(Map reqMap);
}
}
```
协议类复用好不好,提出来探讨,你们有什么好的优化方案?
##### 优化了 Model 层,不为每个功能创建 Model ,由于我的组件化工程, 每个子工程复用 Model
代码大致这样子:
```ruby
@ActivityScope
public class UserModel extends BaseModel
implements UserContract.WxAuthModel, UserContract.BindPhoneModel,
UserContract.AreaCodeModel, UserContract.LoginModel,
UserContract.FindPasswordModel, UserContract.PrepareInfoModel {
@Inject
public UserModel(IRepositoryManager mRepositoryManager) {
super(mRepositoryManager);
}
@Override
public Observable getLoginInfo(Map reqMap) {
return mRepositoryManager.obtainRetrofitService(UserService.class)
.getLoginInfo(reqMap);
}
@Override
public Observable getAreaCodeList(Map reqMap) {
return mRepositoryManager.obtainRetrofitService(UserService.class)
.getAreaCodeList(reqMap);
}
@Override
public Observable getVerificationCode(Map reqMap) {
return mRepositoryManager.obtainRetrofitService(UserService.class)
.getVerificationCode(reqMap);
}
@Override
public Observable putResetPassword(Map reqMap) {
return mRepositoryManager.obtainRetrofitService(UserService.class)
.putResetPassword(reqMap);
}
@Override
public Observable putBindPhoneNumber(Map reqMap) {
return mRepositoryManager.obtainRetrofitService(UserService.class)
.putBindPhoneNumber(reqMap);
}
@Override
public Observable postPrepareInfo(Map reqMap) {
return mRepositoryManager.obtainRetrofitService(UserService.class)
.postPrepareInfo(reqMap);
}
}
```
Model复用好不好,提出来探讨,你们有什么好的优化方案?
经过上面优化可以大幅度 Contract 和 Model 的数量,只需要为每个功能创建 XXXActivity 和 XXXPresenter 类,应该每个功能都有自己的逻辑,所以我不建议复用 XXXPresenter。
这样优化的代价是让 DI 层的 XXXModule 层变得臃肿了
代码如下:
```ruby
@Module
public class UserModule {
private UserContract.WxAuthView wxAuthView;
private UserContract.BindPhoneView bindPhoneView;
private UserContract.AreaCodeView areaCodeView;
private UserContract.LoginView loginView;
private UserContract.FindPasswordView findPasswordView;
private UserContract.PrepareInfoView prepareInfoView;
/**
* 构建 ActivityModule 时,将 View 的实现类传入,这样就可以提供 View 的实现类给 Presenter
* @param view
*/
public UserModule(UserContract.WxAuthView view) {
this.wxAuthView = view;
}
public UserModule(UserContract.BindPhoneView view) {
this.bindPhoneView = view;
}
public UserModule(UserContract.AreaCodeView view) {
this.areaCodeView = view;
}
public UserModule(UserContract.LoginView view) {
this.loginView = view;
}
public UserModule(UserContract.FindPasswordView view) {
this.findPasswordView = view;
}
public UserModule(UserContract.PrepareInfoView view) {
this.prepareInfoView = view;
}
//------ 微信授权 ---------
@ActivityScope
@Provides
UserContract.WxAuthView provideWxAuthView() {
return wxAuthView;
}
@ActivityScope
@Provides
UserContract.WxAuthModel provideWxAuthModel(UserModel model) {
return model;
}
//------ 绑定手机号 ---------
@ActivityScope
@Provides
UserContract.BindPhoneView provideBindPhoneView() {
return bindPhoneView;
}
@ActivityScope
@Provides
UserContract.BindPhoneModel provideBindPhoneModel(UserModel model) {
return model;
}
//------ 选择区号 ---------
@ActivityScope
@Provides
UserContract.AreaCodeView provideAreaCodeView() {
return areaCodeView;
}
@ActivityScope
@Provides
UserContract.AreaCodeModel provideAreaCodeModel(UserModel model) {
return model;
}
//------ 登录 ---------
@ActivityScope
@Provides
UserContract.LoginView provideLoginView() {
return loginView;
}
@ActivityScope
@Provides
UserContract.LoginModel provideLoginModel(UserModel model) {
return model;
}
//------ 发现密码 ---------
@ActivityScope
@Provides
UserContract.FindPasswordView provideFindPasswordView() {
return findPasswordView;
}
@ActivityScope
@Provides
UserContract.FindPasswordModel provideFindPasswordModel(UserModel model) {
return model;
}
//------ 提交预填资料 ---------
@ActivityScope
@Provides
UserContract.PrepareInfoView providePrepareInfoView() {
return prepareInfoView;
}
@ActivityScope
@Provides
UserContract.PrepareInfoModel providePrepareInfoModel(UserModel model) {
return model;
}
//------ Other ---------
@ActivityScope
@Provides
Interrupter provideInterrupter() {
Interrupter nsxInterrupter = new Interrupter();
return nsxInterrupter;
}
}
```
Contributor guide
Assessment
This issue has not been assessed yet.