MVP 架构介绍
MVP(Model-View-Presenter)是一种软件架构模式,常用于构建用户界面(UI)。它将应用程序的逻辑划分为三个部分:Model、View 和 Presenter。MVP 的主要目标是分离视图和业务逻辑,使代码更易于维护和测试。
1. Model
- Model 是应用程序的数据层,负责处理数据和业务逻辑。它通常包括数据访问层(例如数据库、网络请求)和数据操作逻辑。
2. View
- View 是应用程序的用户界面,负责展示数据和接收用户输入。View 不直接处理数据逻辑,而是通过 Presenter 来进行交互。
3. Presenter
- Presenter 是 View 和 Model 之间的中介,负责处理用户输入、更新 UI 和协调 Model。Presenter 从 View 获取用户输入,从 Model 获取数据,并将数据传递给 View 进行显示。
MVP 工作流程
- 用户操作 由 View 接收并传递给 Presenter。
- Presenter 处理用户操作,并与 Model 交互获取数据。
- Model 将数据返回给 Presenter。
- Presenter 将数据处理后传递给 View,更新 UI。
MVP 优点
- 解耦:将视图和业务逻辑分离,代码更易于维护。
- 可测试性:业务逻辑位于 Presenter 中,可以通过单元测试进行测试。
- 可维护性:代码模块化,增强了代码的可读性和可维护性。
MVP Demo 示例
以下是一个简单的 Android MVP 示例,展示了如何使用 MVP 模式来实现一个登录功能。
1. Model
User.java
package com.example.mvp.model;
public class User {
private String username;
private String password;
public User(String username, String password) {
this.username = username;
this.password = password;
}
public String getUsername() {
return username;
}
public String getPassword() {
return password;
}
public boolean isValid() {
return username != null && !username.isEmpty() && password != null && password.length() > 5;
}
}
LoginModel.java
package com.example.mvp.model;
public class LoginModel {
public boolean login(String username, String password) {
// 模拟登录逻辑,这里可以是网络请求或数据库查询
User user = new User(username, password);
return user.isValid();
}
}
2. View
LoginActivity.java
package com.example.mvp.view;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;
import androidx.appcompat.app.AppCompatActivity;
import com.example.mvp.R;
import com.example.mvp.contract.LoginContract;
import com.example.mvp.presenter.LoginPresenter;
public class LoginActivity extends AppCompatActivity implements LoginContract.View {
private EditText editTextUsername;
private EditText editTextPassword;
private Button buttonLogin;
private LoginContract.Presenter presenter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_login);
editTextUsername = findViewById(R.id.editTextUsername);
editTextPassword = findViewById(R.id.editTextPassword);
buttonLogin = findViewById(R.id.buttonLogin);
presenter = new LoginPresenter(this);
buttonLogin.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
presenter.login(editTextUsername.getText().toString(), editTextPassword.getText().toString());
}
});
}
@Override
public void showLoginSuccess() {
Toast.makeText(this, "Login Successful", Toast.LENGTH_SHORT).show();
}
@Override
public void showLoginError() {
Toast.makeText(this, "Login Failed", Toast.LENGTH_SHORT).show();
}
}
3. Presenter
LoginPresenter.java
package com.example.mvp.presenter;
import com.example.mvp.contract.LoginContract;
import com.example.mvp.model.LoginModel;
public class LoginPresenter implements LoginContract.Presenter {
private LoginContract.View view;
private LoginModel model;
public LoginPresenter(LoginContract.View view) {
this.view = view;
this.model = new LoginModel();
}
@Override
public void login(String username, String password) {
if (model.login(username, password)) {
view.showLoginSuccess();
} else {
view.showLoginError();
}
}
}
4. Contract
LoginContract.java
package com.example.mvp.contract;
public interface LoginContract {
interface View {
void showLoginSuccess();
void showLoginError();
}
interface Presenter {
void login(String username, String password);
}
}
总结
在上述示例中,LoginActivity 是 View,负责显示 UI 和接收用户输入。LoginPresenter 是 Presenter,负责处理登录逻辑并与 Model 进行交互。LoginModel 是 Model,负责处理数据逻辑。LoginContract 定义了 View 和 Presenter 之间的接口,使它们之间的依赖关系更加明确。
通过这种方式,业务逻辑和 UI 完全分离,便于测试和维护,提高了代码的可读性和可维护性。