Android MVP模式的初识
MVP是什么?或许在之前更多的人知道的是MVC这个模式(Model View Controller),然而MVP与MVC最不同的一点是M与V是不直接
关联的也是就Model与View不存在直接关系,这两者之间间隔着的是Presenter层。个人感觉这是一种很棒的设计,让代码能够实现充分的解耦。
那么我们还是没有讲到MVP是什么~~~不要急,我会用最简单的方式来叙述,这样好理解~
M(Model):为UI层提供数据,或者是保存UI层的数据;
V(View) :单纯的数据展示,响应用户的操作并且都转发给Presenter来做具体的处理;
P(Presenter):逻辑控制层,从Model处取数据,运算和转化,最后用View来展示;并处理View传过来的用户事件,并做处理;
是不是觉得一目了然了呢~很多第一次学习设计模式的都会有一个这样的疑问,就是设计模式这种东西听上去好像很高大上,那么在什么情
况下我们就应该使用MVP这种设计模式呢?其实:
- 基本上都可以,哪怕只有一个登录的功能,也都是可以使用MVP的,我们初学MVP肯定目标是学习,所以以掌握知识为重,等到理解了,大的项目就 可以使用了;
- MVP它是一个方法论的东西,没有固定的实现方式,只要能体现出它的方法就可以算是MVP。
当然,我们上述所说的感觉给人一点华而不实的感觉,毕竟就这么说谁也不知道MVP到底怎么用,还是要有一点点小规则反而会比较好让我们
去理解:
- Model与View不能直接通信,只能通过Presenter
- Presenter类似于中间人的角色进行协调和调度
- Model和View是接口,Presenter持有的是一个Model接口和一个View接口
- Model和View都应该是被动的,一切都由Presenter来主导
- Model应该把与业务逻辑层的交互封装掉,换句话说Presenter和View不应该知道业务逻辑层
- View的逻辑应该尽可能的简单,不应该有状态。当事件发生时,调用Presenter来处理,并且不传参数,Presenter处理时再调用View的方法来获取。
我们很容易看出,关键的地方还是在Presenter上面,可以说Presenter就是我们整个MVP设计模式的核心部分,那么理论上说了这么多,具体怎么落实呢?
在Android中的实现
MVP是一个方法论的东西,也就是没有任何固定的具体的实现形式,只要能够把View跟Model解除联系,把逻辑都放在Presenter中,那么就能算
得上是MVP,一些具体的实践的指导性原则:
- View是一个接口,负责被动的把处理好的数据显示出来
- Model也是一个接口,负责获取数据和存储数据
- View调用Presenter处理用户事件也是一个接口,称为事件Delegate
- Presenter持有的是View的接口和Model接口
接下来我们使用一个登陆的例子来说明:
登陆View的接口:
public interface ILoginView { void clearEditText(); void showProgress(); void hideProgress(); void setUsernameError(); void setPasswordError(); String getUsername(); String getPassword(); void loginSuccess(); }
登陆Presenter接口:
public interface ILoginPresenter { void doLogin(String username, String password); void clear(); void onDestroy(); }
实现Presenter接口:
public class LoginPresenter implements ILoginPresenter { private ILoginView mLoginView; private User mUser; public LoginPresenter(ILoginView loginView) { this.mLoginView = loginView; initUser(); } private void initUser() { mUser = new User(mLoginView.getUsername(), mLoginView.getPassword()); } @Override public void doLogin(String username, String password) { mLoginView.showProgress(); new Handler().postDelayed(new Runnable() { @Override public void run() { mLoginView.hideProgress(); int code = mUser.checkUserValidity(mLoginView.getUsername(), mLoginView.getPassword()); if (code == -1) { mLoginView.setPasswordError(); } else if (code == 0) { mLoginView.loginSuccess(); } } }, 2000); } @Override public void clear() { mLoginView.clearEditText(); } @Override public void onDestroy() { mLoginView = null; } }
定义Model:
public class User { private String username; private String password; public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } public User(String username, String password) { this.username = username; this.password = password; } public int checkUserValidity(String username, String password) { if (username == null || password == null || username.isEmpty() || password.isEmpty()) { return -1; } return 0; } }
在Activity中实现view:
public class LoginActivity extends AppCompatActivity implements ILoginView, View.OnClickListener { private ILoginPresenter mLoginPresenter; @Bind(R.id.et_username) EditText etUsername; @Bind(R.id.et_passwrod) EditText etPasswrod; @Bind(R.id.bt_enter) Button btEnter; @Bind(R.id.bt_clear) Button btClear; @Bind(R.id.progress) ProgressBar progress; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); ButterKnife.bind(this); mLoginPresenter = new LoginPresenter(this); btEnter.setOnClickListener(this); btClear.setOnClickListener(this); } @Override public void clearEditText() { etPasswrod.setText(""); etUsername.setText(""); } @Override public void showProgress() { progress.setVisibility(View.VISIBLE); } @Override public void hideProgress() { progress.setVisibility(View.GONE); } @Override public void setUsernameError() { etUsername.setError("username error"); } @Override public void setPasswordError() { etPasswrod.setError("password error"); } @Override public String getUsername() { return etUsername.getText().toString(); } @Override public String getPassword() { return etPasswrod.getText().toString(); } @Override public void loginSuccess() { //start act Main Toast.makeText(this, "login success", Toast.LENGTH_SHORT); finish(); } @Override public void onClick(View v) { switch (v.getId()){ case R.id.bt_clear: mLoginPresenter.clear(); break; case R.id.bt_enter: mLoginPresenter.doLogin(etUsername.getText().toString(), etPasswrod.getText().toString()); break; } } @Override protected void onDestroy() { mLoginPresenter.onDestroy(); super.onDestroy(); } }
这样一来是不是对MVP的理解就更加深刻了一点呢,如果没有看懂最好是自己动手敲一遍,会理解的更快哦~~~~~