1 背景 MVC
平时开发APP时会发现,activity职责非常重。以MVC角度来看:
M:model数据操作层(网络请求,耗时操作,数据存取,其他逻辑操作)
V:view,指xml布局文件,其实并没有做更新UI操作
C:controller,指Activity,处理用户交互,操作model存取数据,更新UI
当activity业务繁杂时,这种模式有几点弊端:
- 所有代码都充斥在activity中,不便于后期维护
- model和view耦合度高,不利于分层
- 不方便写测试用例,测试model层数据是否正确
2 MVP
有一种解耦方法呢?有,那就是MVP模式:
M:model数据操作层(网络请求,耗时操作,数据存取,其他逻辑操作)
V:View,Activity,接受用户交互,获取数据,更新UI。不关心页面逻辑和数据操作
P:Presentor,处理用户交互,操作model存取数据,处理完成,通知View(activity)并回调数据,由View更新UI。使model和view解耦。
两者相比较:
1 MVP对于MVC的改进,把交互逻辑交给presentor去做,avtivity本身只做更新UI操作。
2 这种观点是站在APP局部代码来分析看待的,对于小型APP没有必要,会新建很多文件。大型APP和交互复杂的可以这么处理。
3 实现
每一个activity继承自对应的view,实现对应的接口,初始化presentor对象。当接受到用户交互请求,交给presentor逻辑处理,presentor持有view接口,操作model存储数据,处理成功,将返回结果回调view接口对象,这样activity就可以更新UI。目录结构:
bean : 数据实体(略)
model :数据操作层
1 /** 2 * Model 层抽象接口(数据操作) 3 * Created by zhangc on 2018/6/15. 4 */ 5 6 public interface ILoginModel { 7 8 //登录 9 void login(String username, String password); 10 11 //存入User数据 12 void setUser(User user); 13 14 //获取User对象 15 User getUser(); 16 17 void clear(); 18 }
presentor:逻辑处理层
1 /** 2 * Created by zhangc on 2018/6/15. 3 */ 4 5 public class LoginPresentor { 6 7 private IUserLoginView loginView; 8 private ILoginModel model; 9 10 //构造方法 11 public LoginPresentor(IUserLoginView loginView) { 12 this.loginView = loginView; 13 model = new LoginModelImpl(); 14 } 15 16 //供View层调用 17 public void login(String username, String password) { 18 model.login(username,password); 19 } 20 21 //供View层调用 22 public void clear() { 23 loginView.clear(); 24 } 25 }
view:数据更新接口
1 public interface IUserLoginView { 2 //等待框 3 void showLoadingDialog(); 4 //登录成功 5 void loginSuccess(); 6 //登录失败 7 void loginFail(); 8 void clear(); 9 }
activity使用:
1 public class LoginActivity extends FragmentActivity implements IUserLoginView { 2 3 private EditText mEtUsername, mEtPassword; 4 private Button mBtnLogin, mBtnClear; 5 private LoginPresentor presentor; 6 7 @Override 8 protected void onCreate(Bundle savedInstanceState) { 9 super.onCreate(savedInstanceState); 10 setContentView(R.layout.activity_login); 11 intView(); 12 } 13 14 private void intView() { 15 mEtUsername = (EditText) findViewById(R.id.et_login_name); 16 mEtPassword = (EditText) findViewById(R.id.et_login_pwd); 17 mBtnLogin = (Button) findViewById(R.id.btn_login); 18 mBtnClear = (Button) findViewById(R.id.btn_reset); 19 presentor = new LoginPresentor(this); 20 mBtnLogin.setOnClickListener(new View.OnClickListener() { 21 @Override 22 public void onClick(View view) { 23 presentor.login(mEtUsername.getText().toString(), mEtPassword.getText().toString()); 24 } 25 }); 26 } 27 28 @Override 29 public void loginSuccess() { 30 //更新UI 或 跳转页面 31 } 32 }