一、概述
MVC结构
M(model):业务逻辑和实体模型 V(view):布局文件 C(controller):Activity 说明:三层耦合在一起,会非常臃肿,难以扩展维护。
MVP结构
M(model):业务逻辑和实体模型 V(view):布局文件+Activity/Fragment+View组件+简单用户交互(不包含业务逻辑) P(presenter):负责view和model的交互。 说明:presenter会将view和model分隔开,自己作为交互的桥梁,实现解耦。
二者中的model说明:业务逻辑和实体模型。 业务逻辑包含:网络请求、数据存储、数据流转、数据验证等等。 实体模型:bean对象。
交互
1、MVC是M和V可以直接交互。 2、MVP是M和V不能直接交互,它们是通过P进行交互的。
二、代码示例
使用最常见的登录案例,代码实现过程描述:Presenter主要用于分离view和model,它和两层都有交互,所以持有view和model的引用。当然view和model都需要和Presenter交互,他们分别持有Presenter的引用。 当用户点击登录时,view层要通过Presenter层的validatedLogin方法,实际调用model层的login方法验证登录;model层通过Presenter层的OnLoginFinishedListener的方法,将各种登录结果返回给view层展示出来。
1)Presenter
1.1 Presenter层 添加 view–>model的桥梁方法
public interface LoginPresenter {
void validatedLogin(UserBean loginUser);
void clear();
}
1.2 Presenter层 添加 model–>view的桥梁方法
public interface OnLoginFinishedListener {
void onLoginFailedByAccountError();
void onLoginFailedByPasswordError();
void onLoginFailedByOtherError();
void onLoginSuccess();
}
1.3 Presenter层 实现 view和model的真实交互。
public class LoginPresenterImpl implements LoginPresenter, OnLoginFinishedListener {
private LoginModel loginModel = new LoginModelImpl();
private LoginView loginView;
public LoginPresenterImpl(LoginView loginView) {
this.loginView = loginView;
}
@Override
public void validatedLogin(UserBean loginUser) {
if (loginView != null) {
loginView.showProgress();
}
loginModel.login(loginUser, this);
}
@Override
public void clear() {
loginView = null;
}
@Override
public void onLoginFailedByAccountError() {
if (loginView != null) {
loginView.hideProgress();
loginView.onAccountError();
}
}
@Override
public void onLoginFailedByPasswordError() {
if (loginView != null) {
loginView.hideProgress();
loginView.onPasswordError();
}
}
@Override
public void onLoginFailedByOtherError() {
if (loginView != null) {
loginView.hideProgress();
loginView.onOtherError();
}
}
@Override
public void onLoginSuccess() {
if (loginView != null) {
loginView.hideProgress();
}
}
}
2)Model
2.1 Model层 创建 实体模型
public class UserBean {
private String phoneNumber;
private String passWord;
public String getPhoneNumber() {
return phoneNumber;
}
public void setPhoneNumber(String phoneNumber) {
this.phoneNumber = phoneNumber;
}
public String getPassWord() {
return passWord;
}
public void setPassWord(String passWord) {
this.passWord = passWord;
}
}
2.2 Model层 添加 登录验证的方法
public interface LoginModel {
void login(UserBean loginUser, OnLoginFinishedListener listener);
}
2.3 Model层 实现 登录验证的方法
public class LoginModelImpl implements LoginModel {
@Override
public void login(UserBean loginUser, OnLoginFinishedListener listener) {
final String phoneNumber = loginUser.getPhoneNumber();
final String password = loginUser.getPassWord();
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
boolean error = false;
if (TextUtils.isEmpty(phoneNumber)) {
listener.onLoginFailedByAccountError();
error = true;
}
if (TextUtils.isEmpty(password)) {
listener.onLoginFailedByPasswordError();
error = true;
}
if (!error) {
listener.onLoginSuccess();
}
}
}, 2000);
}
}
3)View
3.1 View层 添加 展示登录结果的方法
public interface LoginView {
void showProgress();
void hideProgress();
void onAccountError();
void onPasswordError();
void onOtherError();
void loginSuccess();
}
3.2 View层 实现 展示登录结果的方法
public class LoginActivity extends AppCompatActivity implements LoginView {
private LoginPresenter loginPresenter;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_login);
loginPresenter = new LoginPresenterImpl(this);
initView();
}
private void initView() {
EditText editText_account = findViewById(R.id.editText_account);
EditText editText_password = findViewById(R.id.editText_password);
findViewById(R.id.button_login).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
UserBean userBean = new UserBean();
userBean.setPhoneNumber(editText_account.getText().toString());
userBean.setPassWord(editText_password.getText().toString());
loginPresenter.validatedLogin(userBean);
}
});
}
@Override
public void showProgress() {
ToastUtil.show2Style(this,"显示进度条");
}
@Override
public void hideProgress() {
ToastUtil.show2Style(this,"隐藏进度条");
}
@Override
public void onAccountError() {
ToastUtil.show2Style(this,"账号错误");
}
@Override
public void onPasswordError() {
ToastUtil.show2Style(this,"密码错误");
}
@Override
public void onOtherError() {
ToastUtil.show2Style(this,"其他原因错误");
}
@Override
public void loginSuccess() {
ToastUtil.show2Style(this,"登陆成功!");
}
}
|