Android MVP 和 MVVM 使用场景
在 Android 开发中,MVP(Model-View-Presenter)和 MVVM(Model-View-ViewModel)是两种常见的架构模式。它们都旨在解决传统的 MVC(Model-View-Controller)模式中的问题,并提供更好的代码组织和测试的能力。本文将介绍这两种模式的使用场景,并提供相应的代码示例。
MVP(Model-View-Presenter)
MVP 架构模式主要用于解决界面逻辑和业务逻辑的分离问题。它将界面(View)和业务逻辑(Presenter)分开,通过一个中间层(Model)进行交互。这样可以简化界面的逻辑,提高代码的可维护性和可测试性。
在 MVP 中,View 负责展示数据和接收用户输入,Presenter 负责处理业务逻辑和与 Model 进行交互,Model 则负责数据的获取和处理。下面是一个使用 MVP 架构的登录示例:
// View 接口
public interface LoginView {
void showLoading();
void hideLoading();
void showError(String message);
void showSuccess();
}
// Presenter
public class LoginPresenter {
private LoginView view;
private UserRepository userRepository;
public LoginPresenter(LoginView view, UserRepository userRepository) {
this.view = view;
this.userRepository = userRepository;
}
public void login(String username, String password) {
view.showLoading();
userRepository.login(username, password, new UserRepository.Callback() {
@Override
public void onSuccess() {
view.hideLoading();
view.showSuccess();
}
@Override
public void onError(String message) {
view.hideLoading();
view.showError(message);
}
});
}
}
// Model
public class UserRepository {
public interface Callback {
void onSuccess();
void onError(String message);
}
public void login(String username, String password, Callback callback) {
// 模拟登录请求
if (username.equals("admin") && password.equals("123456")) {
callback.onSuccess();
} else {
callback.onError("Invalid username or password");
}
}
}
在上面的示例中,View 接口定义了一系列展示界面的方法,Presenter 负责处理登录逻辑并通过回调方式通知 View。Model 是一个 UserRepository 类,负责模拟登录请求并返回结果。通过这种方式,界面逻辑和业务逻辑被有效地分离,每个部分的职责清晰明确。
MVVM(Model-View-ViewModel)
MVVM 是一种用于解决界面和数据绑定的架构模式。它将界面(View)和数据(Model)之间的关联交给了一个中间层(ViewModel)来处理。ViewModel 负责从 Model 中获取数据,并将其转换为界面可用的形式,同时也负责处理用户交互的逻辑。下面是一个使用 MVVM 架构的登录示例:
// View
public class LoginActivity extends AppCompatActivity {
private LoginViewModel viewModel;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_login);
viewModel = ViewModelProviders.of(this).get(LoginViewModel.class);
final EditText usernameEditText = findViewById(R.id.usernameEditText);
final EditText passwordEditText = findViewById(R.id.passwordEditText);
final Button loginButton = findViewById(R.id.loginButton);
loginButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
String username = usernameEditText.getText().toString();
String password = passwordEditText.getText().toString();
viewModel.login(username, password);
}
});
viewModel.getLoginResult().observe(this, new Observer<LoginResult>() {
@Override
public void onChanged(LoginResult result) {
if (result.isLoading()) {
showLoading();
} else {
hideLoading();
if (result.isSuccess()) {
showSuccess();
} else {
showError(result.getError());
}
}
}
});
}
private void showLoading() {
// 显示加载中的 UI
}
private void hideLoading() {
// 隐藏加载中的 UI
}
private void showError(String message) {
// 显示错误提示
}
private void showSuccess() {
// 显示登录成功提示
}
}
// ViewModel
public class LoginViewModel extends ViewModel {
private MutableLiveData<LoginResult> loginResult = new MutableLiveData<>();
private UserRepository userRepository;
public LoginViewModel() {
userRepository = new UserRepository();
}
public LiveData<LoginResult> getLoginResult() {
return loginResult;