Thiết kế mô hình MVP trong Android

Mô hình MVP trong Android (Model – View – Presenter) là một mô hình kiến trúc hướng giao diện người dùng giúp tách tầng trình diễn ra khỏi tầng dữ liệu. MVP Pattern trong Android mang lại lợi thế dễ dàng mở rộng một cách nhanh chóng, dễ dàng bảo trì và dễ dàng kiểm thử.

Mô hình MVP trong Android viết tắt của Model – View – Presenter, đây là mô hình kiến trúc hiện đang được nhiều lập trình viên lựa chọn sử dụng.

1. Mô hình MVP là gì?

Mô hình MVP trong Android giúp tách tầng trình diễn ra khỏi tầng dữ liệu, việc sử dụng MVP Pattern sẽ giúp dễ dàng mở rộng một cách nhanh chóng, dễ dàng bảo trì và dễ dàng kiểm thử ứng dụng.

MVC, MVP, MVVM là những Design Pattern tốt nhất thường được các lập trình viên sử dụng khi xây dưng ứng dụng Android, bạn đang sử dụng Design Pattern nào?

2. Mô hình MVP bao gồm?

[Ứng dụng tra cứu thị trường] Bài 7 Thiết kế mô hình MVP trong Android

  • Model: phụ trách xử lý tầng dữ liệu có thể là các thực thể (Entities), API Services, SQLite, SharedPreferences, Realm Database, helpers…
  • View: phụ trách trình bày cách dữ liệu hiển thị, tiếp nhận tương tác từ người dùng sau đó gọi đến Presenter xử lý tương tác.
  • Presenter: phụ trách tiếp nhận các yêu cầu từ View sau gọi sự kiện xử lý tương ứng, có thể sẽ lấy dữ liệu từ Model và cuối cùng đẩy dữ liệu cho View hiển thị.

3. Thiết kế mô hình MVP trong Android

Trong ứng dụng tra cứu thị trường chúng ta sẽ thiết kế mô hình MVP trong Android cụ thể như sau:

Bước 1: Đầu tiên bạn tạo lớp TyGiaView.java nhằm để hiển thị dữ liệu, lớp này sẽ được implement tại TyGiaActivity.

package com.teamvietdev.tracuuthitruong.listener;

import com.teamvietdev.tracuuthitruong.model.TyGia;

public interface TyGiaView {

    public void onComplete(TyGia tyGia);

    public void onError(String msg);

}

Bước 2: Tiếp theo bạn tao lớp TyGiaPresenter.javaTyGiaPresenterImpl.java sử dụng để xử lý các yêu cầu từ phía View, truy vấn dữ liệu từ Model và sau đó đẩy dữ liệu cho View hiển thị.

Lớp TyGiaPresenter.java như sau:

package com.teamvietdev.tracuuthitruong.presenter;

public interface TyGiaPresenter {

    public void loadData(String token);

}

Lớp TyGiaPresenterImpl.java như sau:

package com.teamvietdev.tracuuthitruong.presenter;

import com.teamvietdev.tracuuthitruong.listener.TyGiaView;
import com.teamvietdev.tracuuthitruong.model.TyGia;
import com.teamvietdev.tracuuthitruong.retrofit.ApiClient;

import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;

public class TyGiaPresenterImpl implements TyGiaPresenter{

    private TyGiaView tyGiaView;
    private ApiClient apiClient;

    public TyGiaPresenterImpl(TyGiaView tyGiaView) {
        this.tyGiaView = tyGiaView;
        this.apiClient = new ApiClient();
    }

    @Override
    public void loadData(String token) {
        Call<TyGia> call = apiClient.getClient().getListTyGiaNgoaiTe(token);
        call.enqueue(new Callback<TyGia>() {
            @Override
            public void onResponse(Call<TyGia> call, Response<TyGia> response) {
                if (response.body() != null) {
                    tyGiaView.onComplete(response.body());
                } else {
                    tyGiaView.onError("null");
                }
            }

            @Override
            public void onFailure(Call<TyGia> call, Throwable throwable) {
                tyGiaView.onError(throwable.getMessage().toString());
            }
        });
    }

}

Bước 3: Cuối cùng tại lớp TyGiaActivity.java bạn sẽ khởi tạo Presenter, gọi sự kiện tải dữ liệu và trình bày hiển thị dữ liệu lên màn hình.

package com.teamvietdev.tracuuthitruong.view.tygia;

import android.os.Bundle;
import android.support.design.widget.FloatingActionButton;
import android.support.design.widget.Snackbar;
import android.support.v4.widget.SwipeRefreshLayout;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.Toolbar;
import android.view.View;
import android.widget.Toast;

import com.teamvietdev.tracuuthitruong.R;
import com.teamvietdev.tracuuthitruong.adapter.TyGiaAdapter;
import com.teamvietdev.tracuuthitruong.listener.DividerItemDecoration;
import com.teamvietdev.tracuuthitruong.listener.TyGiaView;
import com.teamvietdev.tracuuthitruong.model.NgoaiTe;
import com.teamvietdev.tracuuthitruong.model.TyGia;
import com.teamvietdev.tracuuthitruong.presenter.TyGiaPresenter;
import com.teamvietdev.tracuuthitruong.presenter.TyGiaPresenterImpl;

import java.util.ArrayList;
import java.util.List;

public class TyGiaActivity extends AppCompatActivity implements TyGiaView {

    private Toolbar toolbar;
    private RecyclerView recyclerView;
    private SwipeRefreshLayout swipeRefreshLayout;

    private TyGia tyGia = null;
    private List<NgoaiTe> listNgoaiTe = null;

    private TyGiaPresenter tyGiaPresenter;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_ty_gia);
        toolbar = (Toolbar) findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);

        FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
        fab.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_LONG)
                        .setAction("Action", null).show();
            }
        });

        tyGiaPresenter = new TyGiaPresenterImpl(this);

        swipeRefreshLayout = (SwipeRefreshLayout) findViewById(R.id.swipeRefresh);
        swipeRefreshLayout.setColorSchemeResources(R.color.colorAccent);
        swipeRefreshLayout.setRefreshing(true);

        recyclerView = (RecyclerView) findViewById(R.id.recyclerView);
        recyclerView.setLayoutManager(new LinearLayoutManager(this));
        recyclerView.addItemDecoration(new DividerItemDecoration(getApplicationContext(), LinearLayoutManager.VERTICAL));

        swipeRefreshLayout.setOnRefreshListener(
                new SwipeRefreshLayout.OnRefreshListener() {
                    @Override
                    public void onRefresh() {
                        swipeRefreshLayout.setRefreshing(true);
                        tyGiaPresenter.loadData("teamvietdev.com");
                    }
                }
        );

        swipeRefreshLayout.setRefreshing(true);
        tyGiaPresenter.loadData("teamvietdev.com");

    }

    @Override
    public void onComplete(TyGia tyGia) {
        listNgoaiTe = tyGia.getDanh_sach_ngoai_te();
        toolbar.setTitle("NGOẠI TỆ (" + tyGia.getThoi_gian_tra_cuu() + ")");
        setSupportActionBar(toolbar);
        recyclerView.setAdapter(new TyGiaAdapter(listNgoaiTe));
        swipeRefreshLayout.setRefreshing(false);
    }

    @Override
    public void onError(String msg) {
        toolbar.setTitle("NGOẠI TỆ");
        setSupportActionBar(toolbar);
        listNgoaiTe = new ArrayList<>();
        recyclerView.setAdapter(new TyGiaAdapter(listNgoaiTe));
        swipeRefreshLayout.setRefreshing(false);
        Toast.makeText(getApplicationContext(), msg, Toast.LENGTH_SHORT).show();
    }

}

Cấu trúc thư mục mô hình MVP trong Android như sau:

[Ứng dụng tra cứu thị trường] Bài 7 Thiết kế mô hình MVP trong Android

Bạn có thể tải mã nguồn hướng dẫn thiết kế mô hình MVP trong Android thông qua ứng dụng Android tra cứu thị trường tại Github:

Lời kết: MVC, MVP, MVVM là những Design Pattern tốt nhất thường được các lập trình viên sử dụng khi xây dưng ứng dụng Android, còn bạn nghĩ đâu là Design Pattern tốt nhất?. Hẹn gặp lại các bạn trong các bài viết tiếp theo trong chuyên mục lập trình Android phần hướng dẫn xây dựng ứng dụng tra cứu thị trường.

(Tác giả: Team Việt Dev)

Bình luận