JavaRush /Java Blog /Random-ID /MVP di Android untuk si kecil

MVP di Android untuk si kecil

Dipublikasikan di grup Random-ID
Ketika saya memulai perjalanan saya sebagai pengembang Android, kata "Arsitektur Aplikasi Seluler" membuat saya sangat bingung, Google dan artikel di Habré membuat saya semakin depresi - saya melihat buku dan tidak melihat apa pun. Saya rasa jika Anda membaca artikel ini, Anda telah mempelajari gambaran ini lebih dari sekali dan mencoba memahami apa yang terjadi: MVP di Android untuk si kecil - 1Masalah pemahaman pendekatan arsitektur dalam pengembangan seluler, menurut saya, terletak pada keabstrakan arsitektur itu sendiri. Setiap pengembang memiliki visinya sendiri tentang cara menerapkan pola tertentu dengan benar. Contoh penerapan MVP yang kurang lebih baik ditemukan di sektor Internet berbahasa Inggris, dan hal ini tidak mengherankan. Mari kita lihat secara singkat apa itu dan beralih ke sebuah contoh. Model - tingkat data. Saya tidak suka menggunakan istilah “logika bisnis”, jadi dalam aplikasi saya, saya menyebutnya Repositori dan berkomunikasi dengan database dan jaringan. Lihat — tingkat tampilan. Ini akan menjadi Activity , Fragment atau Custom View jika Anda tidak suka menari dengan rebana dan berinteraksi dengan siklus hidup. Izinkan saya mengingatkan Anda bahwa awalnya semua aplikasi Android berada di bawah struktur MVC , di mana Pengontrolnya adalah Aktivitas atau Fragmen . Presenter adalah lapisan antara View dan Model. View mentransmisikan peristiwa yang terjadi padanya, presenter memprosesnya, jika perlu, mengakses Model dan mengembalikan data ke View untuk dirender. Sehubungan dengan Android dan contoh spesifiknya, saya akan menyoroti bagian penting - Kontrak. Ini adalah antarmuka yang menjelaskan semua interaksi antara komponen di atas. Untuk meringkas bagian teoritis:
  • Lihat mengetahui tentang Presenter;
  • Presenter mengetahui tentang View dan Model (Repositori);
  • Model dengan sendirinya;
  • Kontrak mengatur interaksi di antara mereka.
Sebenarnya contohnya sendiri, untuk kesederhanaan percobaan, dengan mengklik sebuah tombol, kita akan memuat baris dari database dan menampilkannya dalam TextView . Misalnya, database berisi daftar restoran terbaik di kota. Mari kita mulai dengan kontraknya: Mari kita membuat antarmuka MainContract:
public interface MainContract {
    interface View {
        void showText();
    }

    interface Presenter {
        void onButtonWasClicked();
        void onDestroy();
    }

    interface Repository {
        String loadMessage();
    }
}
Untuk saat ini, kami hanya menyoroti 3 komponen aplikasi masa depan kami dan apa yang akan dilakukannya. Selanjutnya kami akan menjelaskan Repositori:
public class MainRepository implements MainContract.Repository {

    private static final String TAG = "MainRepository";
    @Override
    public String loadMessage() {
        Log.d(TAG, "loadMessage()");
        /** Здесь обращаемся к БД or сети.
         * Я специально ничего не пишу, чтобы не загромождать пример
         * DBHelper'ами и прочими не относяшимеся к теме an objectми.
         * Поэтому я буду возвращать строку Сосисочная =)
         */
        return "Сосисочная у Лёхи»;
    }
}
Semuanya jelas dengan itu, hanya memuat dan membongkar data. Selanjutnya adalah Pembawa Acara:
public class MainPresenter implements MainContract.Presenter {
    private static final String TAG = "MainPresenter";

    //Компоненты MVP applications
    private MainContract.View mView;
    private MainContract.Repository mRepository;

    //Сообщение
    private String message;


    //Обрати внимание на аргументы конструктора - мы передаем экземпляр View, а Repository просто создаём конструктором.
    public MainPresenter(MainContract.View mView) {
        this.mView = mView;
        this.mRepository = new MainRepository();
        Log.d(TAG, "Constructor");
    }

    //View сообщает, что кнопка была нажата
    @Override
    public void onButtonWasClicked() {
        message = mRepository.loadMessage();
        mView.showText(message);
        Log.d(TAG, "onButtonWasClicked()");
    }

    @Override
    public void onDestroy() {
        /**
         * Если бы мы работали например с RxJava, в этом классе стоило бы отписываться от подписок
         * Кроме того, при работе с другими методами асинхронного андроида,здесь мы боремся с утечкой контекста
         */

        Log.d(TAG, "onDestroy()");
    }
}
Apakah Anda ingat saya menulis tentang menari dengan rebana dan siklus hidup? Presenter hidup selama View-nya hidup, ketika mengembangkan skenario pengguna yang kompleks, saya menyarankan Anda untuk menduplikasi semua callback View di Presenter dan memanggilnya pada saat yang tepat, menduplikasi siklus hidup Aktivitas/Fragmen, untuk memahami pada waktunya apa yang dibutuhkan. harus dilakukan dengan data yang sedang hang di "interlayer". Dan terakhir, Lihat:
public class MainActivity extends AppCompatActivity implements MainContract.View {

    private static final String TAG = "MainActivity";

    private MainContract.Presenter mPresenter;

    private Button mButton;

    private TextView myTv;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        //Создаём Presenter и в аргументе передаём ему this - эта Activity расширяет интерфейс MainContract.View
        mPresenter = new MainPresenter(this);

        myTv = (TextView) findViewById(R.id.text_view);
        mButton = (Button) findViewById(R.id.button);

        mButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                mPresenter.onButtonWasClicked();
            }
        });
        Log.d(TAG, "onCreate()");
    }

    @Override
    public void showText(String message) {
        myTv.setText(message);
        Log.d(TAG, "showMessage()");
    }

    //Вызываем у Presenter метод onDestroy, чтобы избежать утечек контекста и прочих неприятностей.
    @Override
    public void onDestroy() {
        super.onDestroy();
        mPresenter.onDestroy();
        Log.d(TAG, "onDestroy()");
    }
}
Apa yang sedang terjadi?
  • Aktivitas, juga dikenal sebagai View, onCreate()membuat instance Presenter dalam suatu metode dan meneruskan dirinya ke konstruktornya.
  • Saat Presenter dibuat, ia secara eksplisit menerima Tampilan dan membuat instance Repositori (omong-omong, ini bisa dijadikan Singleton)
  • Saat sebuah tombol ditekan, Tampilan mengetuk presenter dan mengatakan: “Tombol telah ditekan.”
  • Presenter membuka Repositori: “Unduh omong kosong ini untuk saya.”
  • Repositori memuat dan mengirimkan “barang” ke Presenter.
  • Presenter beralih ke View: “Ini datanya untuk Anda, gambarlah”
Itu saja, teman-teman. PS Penting untuk menggambarkan dengan jelas tanggung jawab antar komponen. Misalnya, dalam salah satu proyek pelatihan saya, saat mengklik tombol, data di database perlu diubah. Modelnya dideskripsikan oleh kelas POJO, saya meneruskan informasi tentang lokasi tampilan, yang bertanggung jawab atas informasi tentang objek di layar, Presenter mencari objek ini dalam daftar dan mengirimkannya untuk ditulis ke Repositori. Apakah semuanya tampak logis? Namun mentor saya menunjukkan hal berikut: Repositori HANYA boleh menulis dan membaca, tidak boleh mengeluarkan informasi yang diperlukan dari POJO dan memutuskan apa yang perlu ditulis. Presenter harus memberinya hanya informasi untuk dicatat dan tidak lebih. Tidak ada kerangka ketat untuk mengimplementasikan arsitektur: bereksperimen, coba, cari apa yang nyaman bagi Anda secara pribadi. Dan jangan lupa untuk menunjukkan kepada rekan senior Anda pada review kode =) Contohnya tersedia di GitHub: https://github.com/admitrevskiy/MVP_Example
Komentar
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION