MVP là một mô hình kiến trúc hướng giao diện người dùng, được thiết kế để tạo thuận lợi cho việc kiểm thử đơn vị (unit testing) và tăng tính tách biệt giữa tầng dữ liệu và tầng hiển thị dữ liệu trong mô hình MVC. Đây là mô hình đang được áp dụng khá nhiều trong ứng dụng Android.
Mô hình MVP cho phép tách tầng trình diễn (Presenter) ra khỏi tầng dữ liệu (Model), vì vậy tương tác với giao diện được tách biệt với cách chúng ta biểu diễn nó trên màn hình (View), hay nói cách khác, tất cả logic sẽ được tách ra và đưa vào tầng trình diễn (Presenter). Thiết kế lý tưởng nhất là với cùng một logic được áp dụng cho nhiều View khác nhau và hoán đổi được cho nhau.
1. Tìm hiểu chi tiết
Có rất nhiều biến thể cũng như phương pháp triển khai MVP, tất cả mọi người có thể điều chỉnh mô hình này tùy theo nhu cầu và cách họ cảm thấy thoải mái hơn. Nhưng tất cả vẫn phải dựa vào các quy tắc chung trên Model - View - Prensenter.
Model: Cái này thì các bạn rất quen thuộc rồi, nó không có gì khác với các mô hình khác, dùng để mô tả, chứa dữ liệu . Ví dụ ta có model Animal, Bike …
View: Thường được implement bởi một Activity , Fragment, View ... tùy thuộc vào cấu trúc ứng dụng, View này sẽ chứa một thuộc tính là một lớp Presenter.
Presenter: Tầng trình diễn có trách nhiệm như một cầu nối giữa View và Model. Nó lấy dữ liệu từ Model, định dạng và trả về cho View. Nhưng không giống như MVC, nó cũng quyết định những gì sẽ xảy ra khi người dùng tương tác với View, hay nói cách khác nó hàm chứa logic ứng dụng. Lý tưởng nhất Presenter nên được cung cấp bởi một Dependency Injection framewok như Dagger, nhưng trong trường hợp ứng dụng không sử dụng một thư viện hay framework như vậy ta hoàn toàn có thể tạo ra các đối tượng Presenter.
2. Lý do nên dùng
Điều đầu tiên mà chúng ta có thể dễ dàng nhận thấy là MVP phân chia các lớp một cách rành mạch so với MVC. Trong mô hình MVC, View và Model có thể tương tác lẫn nhau tức là chúng ta thường có xu hướng đưa nhiều các xử lý bên ngoài vào View. Hệ quả là View sẽ chứa rất nhiều các xử lý liên quan đến business logic và data logic. Và như vậy chúng ta cần phải phân tách 2 lớp xử lý này một cách rành mạch giống như MVP đã làm.
Trong quá trình phát triển phần mềm, View là lớp mà có khả năng sẽ thay đổi nhiều nhất nên việc phân tách sẽ giúp thay đổi View một cách độc lập mà không ảnh hướng đến các thành phần khác.
Với mô hình MVP, việc viết Unit Tests sẽ đơn giản hơn rất nhiều. Bởi vì giờ đây Presenter và Model layer sẽ thuần là code java xử lý logic
Có thể giúp giảm thiểu lượng code trong ứng dụng cũng như gộp các xử lý, logic trong ứng dụng vào cùng một nơi.
3. Demo thử màn Login
Mình sẽ cùng các bạn làm một demo cơ bản về xử lý màn Login theo mô hình MVP
Bước 1: Tạo Model
User.class
public class User {
public String username;
public String password;
public User(String username, String password) {
this.username = username;
this.password = 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;
}
}
Bước 2: Tạo 1 interface tên là LoginView chứa các phương thức tác động tới giao diện
LoginView.class
public interface LoginView {
void loginFail();
void loginSuccessful();
void goHome();
}
Bước 3: Tạo các phương thức xử lý dữ liệu trong class LoginPresenter
LoginPresenter.class
public class LoginPresenter {
LoginView loginView;
public LoginPresenter(LoginView loginView) {
this.loginView = loginView;
}
public void login(String username, String password) {
if (username.equalsIgnoreCase("admin")
&& password.equalsIgnoreCase("admin")) {
loginView.loginSuccessful();
loginView.goHome();
} else {
loginView.loginFail();
}
}
}
Bước 4: Cuối cùng, ta bắt các sự kiện và xử lý ở class LoginActivity
LoginActivity.class
public class LoginActivity extends AppCompatActivity implements LoginView, View.OnClickListener {
private EditText edtUsername;
private EditText edtPassword;
private Button btnLogin;
LoginPresenter loginPresenter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
loginPresenter = new LoginPresenter(this);
initView();
initClick();
}
public void initView() {
edtUsername = findViewById(R.id.edtUsername);
edtPassword = findViewById(R.id.edtPassword);
btnLogin = findViewById(R.id.btnLogin);
}
public void initClick() {
btnLogin.setOnClickListener(this);
}
@Override
public void loginSuccessful() {
Toast.makeText(this, "Login Thanh Cong!!",
Toast.LENGTH_SHORT).show();
}
@Override
public void loginFail() {
Toast.makeText(this, "Login Fail!!",
Toast.LENGTH_SHORT).show();
}
@Override
public void goHome() {
startActivity(new Intent(this, HomeActivity.class));
}
@Override
public void onClick(Viewview) {
if (view.getId() == R.id.btnLogin) {
String username = edtUsername.getText().toString();
String password = edtPassword.getText().toString();
loginPresenter.login(username, password);
}
}
}
4. Kết luận
Mô hình MVP đến nay vẫn đang được dùng khá phổ biến. Vấn đề quan trọng bạn cần nhớ là Presenter sẽ làm công việc logic. Ở một số hệ thống người ta còn dùng thêm các interactor, tuy nhiên bản chất vẫn thế. Mối liên hệ giữa view là presenter là 1-1. Nhưng có một lưu ý bạn cần chú ý là
Nhược điểm lớn nhất của mô hình MVP là theo thời gian, Presenter sẽ dần lớn lên do bị thêm các business logic rải rác. Người dùng sẽ rất khó để kiểm soát và chia nhỏ code khi Presenter đã quá lớn.
Комментарии